【问题标题】:Getters and setters in PythonPython 中的 getter 和 setter
【发布时间】:2018-05-11 15:44:55
【问题描述】:

我是 Python 的新手,我正在尝试编写一个类,它只存储两个属性,其中一个是数字,另一个是日期时间对象。虽然我也想在将date 存储为日期时间的同时,使用“dd.mm.yyyy”之类的字符串对其进行初始化和输出。所以我走了:

class MyClass:
    number = None
    date = None

    def __init__(self, params):
        self.number = params["number"]
        self.date = params["date"]

    @property
    def date(self):
        return datetime.datetime.strftime(self.date, '%d.%m.%Y')

    @date.setter
    def date(self, value):
        self.date = datetime.datetime.strptime(value, '%d.%m.%Y')

    def get_vars(self):
        return vars(self)

但在运行时@property 指向self.date 并说:Expected type 'datetime', got 'str' instead。当它在设置时要转换为日期时,它怎么能得到一个字符串。为什么会这样?困惑。

例如:

>>> MyClass({'number': 42, 'date': '28.12.2017'})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 8, in __init__
  File "<string>", line 16, in date
  File "<string>", line 16, in date
TypeError: strptime() argument 1 must be str, not datetime.datetime

【问题讨论】:

  • 请务必包含完整回溯和创建MyClass 实例的代码。我可以在这个特定的、有限的情况下确切地找出一定发生的事情,但是回溯可以让未来的访问者更容易查看他们是否有同样的问题。

标签: python python-3.x oop datetime properties


【解决方案1】:

您不能同时将date 用于property 对象和实例属性。只有属性可用(因为它是data descriptor),并且self.date 引用该属性对象。表达式self.date = params['date']param['date'] 值传递给setter,它没有设置实例属性。

因为param['date'] 在您的情况下显然是一个datetime 对象,这意味着在setter 中调用datetime.datetime.strptime(&lt;datetime instance&gt;, '%d.%m.%Y'),但失败了。即使成功了,您也会尝试将该结果分配回self.date,这将再次无限期地调用setter。它是一个 datetime 实例,因为您最初传入了 datetime 值,您传入了一个字符串,并且第一个 .strptime() 调用成功,现在正在分配 self.date刚刚创建的 datetime 实例。

重命名实例属性;在这里给它一个前导的单下划线通常是最有用的命名方案:

class MyClass:
    _number = None
    _date = None

    def __init__(self, params):
        self._number = params["number"]
        self._date = params["date"]

    @property
    def date(self):
        return self._date.strftime('%d.%m.%Y')

    @date.setter
    def date(self, value):
        self._date = datetime.datetime.strptime(value, '%d.%m.%Y')

    def get_vars(self):
        return vars(self)

我还将datetime.datetime.strftime(self._date, '%d.%m.%Y')(对未绑定方法的调用)更改为对self._date 的方法调用。

【讨论】:

  • 现在它起作用了,更重要的是,我现在明白为什么了)千感谢)
  • 我能再问你一个问题吗?似乎 vars() 在返回带有属性的字典时不使用 @property 。有没有办法让它使用 getter 以获取正确格式的 data 值?
  • @Dankevich:不,vars() 返回实例属性字典。您必须找到类上的所有属性 (dir(ype(self))),测试每个属性以查看它是否是属性,然后访问实例上的属性,列出这些属性。
  • 它很接近,但不完全是我需要的。我想要一本字典,所有属性都有一个“键”:“值”对,而这个提示只给我属性名称
猜你喜欢
  • 2016-02-24
  • 2020-05-29
  • 2023-03-04
  • 2017-11-22
  • 1970-01-01
  • 2011-10-05
  • 2015-08-05
  • 2016-10-20
  • 1970-01-01
相关资源
最近更新 更多