【问题标题】:TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType类型错误:+ 不支持的操作数类型:“NoneType”和“NoneType”
【发布时间】:2019-08-22 04:21:54
【问题描述】:

我是 Python 的新用户,我遇到了 None 类型的问题,我看了不同的问题,但问题仍然存在。

我的代码正在寻找两个日期之间的星期五和星期六,到目前为止它可以工作,但是当我将两者相加时出现此错误:

"TypeError: + 的不支持的操作数类型: 'NoneType' 和 'NoneType'

我在函数中返回结果后。

这是我的代码:

    # -*- coding: utf-8 -*-

import datetime
import calendar
calendar.setfirstweekday(calendar.SUNDAY)

from odoo import models, fields, api

class HrMission(models.Model):
    _name = "hr.employee.mission"
    _description = "hr mission"
    _inherit = "hr.employee.mission"

    days_compensation =fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos",
                             required=True, readonly=True,)

    @api.multi
    @api.depends('mission_start_date', 'mission_end_date')
    def get_compensation(self):
        for rec in self:
            if rec.mission_start_date and rec.mission_end_date:
                time1 = datetime.datetime.strptime(rec.mission_start_date, "%Y-%m-%d")
                time2 = datetime.datetime.strptime(rec.mission_end_date, "%Y-%m-%d")
                week = {}
                leave_value = {}
        # Compute Number Of Friday And Saturday
                for i in range((time2 - time1).days):
                    day = calendar.day_name[(time1 + datetime.timedelta(days=i+1)).weekday()]
                    week[day] = week[day] + 1 if day in week else 1                    
                fri = week.get('Friday')  # Result Number 4 Of Friday If "Start Date", "End date" --> "01/01/2017", "31/01/2017"
                sat = week.get('Saturday') # Same thing that friday
                friandsat = mon + sat # Error ---> "TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'"
                rec.days_compensation = friandsat

【问题讨论】:

  • 您能告诉我们您遇到的错误,以及显示错误发生位置的堆栈跟踪吗?
  • 如果您在谈论通过调用此方法获得的求和结果,那么我敢打赌您的问题是此方法没有返回值。 - 我不清楚你应该返回什么值。
  • 我知道,这就是问题所在,我想返回 Fridays 和 Saturdays 的值,但它是 NoneType,请帮帮我
  • 哦。对不起。我刚刚注意到您在代码中的评论。从您的代码中我不清楚如何假设 week 将包含键 Frid​​aySaturday
  • 你需要提供一个更完整的例子。我们可以运行的东西,包括导致您看到的问题的示例数据/输入。请查看MCVE

标签: python odoo nonetype


【解决方案1】:

我玩过你的代码。这似乎有点工作。它计算出一系列日期中存在一周中的哪几天。当您的日期范围内既没有星期五又没有星期六时,就会出现您看到的问题(请注意,您有一个名为 'mon' 的变量是通过查找键 'Friday' 来设置的)。

因此,您的问题似乎只是您必须考虑在您提供的日期范围内一周中没有这两天的情况作为输入。在这种情况下,week.get('Friday') 和 week.get('Saturday') 中的一个或两个都不会存在于您的 week 地图中,因此 mon 和/或 sat 将是 None,您将遇到问题。

为了让你的代码运行,我在它下面添加了这个:

class Rec:
    def __init__(self, start, end):
        self.mission_start_date = start
        self.mission_end_date = end

self = [
    Rec("2019-3-31", "2019-4-1")
]

get_compensation(self)

这让我可以让您的代码处理一对日期。如果我在这里给出的日期范围包括星期五和星期六,那么您的代码运行良好。否则,它会因您正在谈论的错误而呕吐。

如果换行:

mon = week.get('Friday')
sat = week.get('Saturday')

到:

mon = week.get('Friday') if 'Friday' in week else 0
sat = week.get('Saturday') if 'Saturday' in week else 0

那么您的代码在我测试过的任何日期范围内都不会崩溃。我不知道它是否正在计算您想要的结果,因为您没有保留或返回任何计算结果。

【讨论】:

  • 对不起,我的意思是“fri”而不是“my”。它没有在两个变量“fri”和“sat”之间求和。请帮助我,我已经花了好几个小时,但我还没有解决问题
  • 我明白你在做什么。我看到了很多解决这个问题的方法。但是您可以做的一件事是检查 Saturday' 键是否在您的 week 字典中。如果没有,那么你算 0 个星期六。周五也一样。您可以做的一件事是初始化您的地图,以便地图以每天的条目开始,每个条目出现 0 次。那么现在出错的代码就可以工作了,因为 week['Saturday'] 总是有一个值。
  • 我认为如果您将有问题的两个关键行更改为fri = week.get('Friday') if 'Friday' in week else 0,您的代码可能会起作用,周六也是如此。
  • 我更新了我的答案以包括我刚才所说的内容。这似乎解决了你的问题。
  • 谢谢^^,比我提到的问题,是delete,但是函数没有返回任何东西,得出的结论是我的值总是零,可以导入日历,不!
【解决方案2】:
  • 需要注意的一点是,开始日期和结束日期是否包含在日期范围内。例如,如果两个日期都是datetime.datetime(2019, 3, 1),那么答案是否应该是1
...
def get_compensation(self):
    def date_range_inclusive(rec):
        # if either date is undefined, then so is date range
        if not rec.mission_end_date or not rec.mission_start_date:
            return iter([])

        # Add 1 for inclusivity of both start and end dates
        num_days = abs((rec.mission_end_date - rec.mission_start_date).days) + 1
        return (rec.mission_start_date + timedelta(days=n) for n in range(num_days))

    for rec in self:
        # date range, including both start and end dates
        dates = date_range_inclusive(rec)
        # desired days to count
        day_selection = (calendar.FRIDAY, calendar.SATURDAY)

        rec.days_compensation = sum([dt.weekday() in day_selection for dt in dates])

上面的代码将假定日期范围包括在内。删除 + 1 使其不包含在内。如果不包括周五或周六,它将把 days_compensation 字段设置为 0。

computed fields are not stored by default, they are computed and returned when requested. Setting store=True will store them in the database and automatically enable searching

因此,您可能想要:

days_compensation = fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos", required=True, readonly=True,
store=True)

请注意,唯一的更新是 store=True

【讨论】:

  • 总是同样的事情没有回报,当我选择两个日期时,字段days_compensation总是null
【解决方案3】:

我认为您可以使用datetime 格式返回两个日期之间的星期五和星期六。就这些。以及检查日期名称是否为必需的条件。

此格式打印日期名称:"%A"

【讨论】:

    【解决方案4】:

    这是为从搜索引擎到达这里的人准备的。 我在导入数据时遇到了这个错误。这是因为我将产品 ID 字段映射到 Product 而不是 Product/External ID。所以如果你在导入数据时遇到这个错误,请检查 id 字段是否映射正确。

    【讨论】:

      猜你喜欢
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-15
      • 2018-07-07
      • 2014-03-16
      相关资源
      最近更新 更多