【问题标题】:How to initialise a instance of a class with current time as attribute如何以当前时间为属性初始化类的实例
【发布时间】:2021-02-19 14:57:30
【问题描述】:

我正在定义一个具有时间属性的类,但默认设置为当前 UTC 时间。

import datetime

class Timer:
    def __init__(self, time = datetime.datetime.utcnow()):
        self.time = time
        print('Instance created at', self.time)
        
        
a = Timer()

问题是一旦定义(或者当它被导入时,如果它在模块中),这个属性就会被永久设置!类的所有新实例“继承”类的时间,在定义时进行评估,而不是在调用__init__ 时生成自己的“当前时间”。为什么每次创建新实例时都不评估获取当前 UTC 时间的函数?

【问题讨论】:

标签: python class datetime initialization


【解决方案1】:

通过为time 定义默认kwarg,在添加/解释类定义对象时评估time,参见函数__defaults__,一个不可变的元组。

>>> class Timer:
...     def __init__(self, time = datetime.datetime.utcnow()):
...         self.time = time
...         print('Instance created at', self.time)
... 
>>> Timer.__init__.__defaults__
# notice how the date is already set here
(datetime.datetime(2021, 2, 19, 15, 22, 42, 639808),)

而您希望在类对象实例化时对其进行评估。

>>> class Timer:
...     def __init__(self, time = None):
...         self.time = time or datetime.datetime.utcnow()
...         print('Instance created at', self.time)
... 
>>> Timer.__init__.__defaults__
(None,)
>>> a = Timer()
Instance created at 2021-02-19 15:04:45.946796
>>> b = Timer()
Instance created at 2021-02-19 15:04:48.313514

【讨论】:

  • 这不是范围界定问题,至少在 Python 中通常使用术语“范围”的意义上不是。问题是在类定义时评估默认参数值,而不是在调用方法时。
  • 谢谢!我想出了一个更简单的例子,它很好地展示了你提出的关于在函数定义时如何修复默认参数的问题:`def givemetime(time = datetime.datetime.now()): print(time)' '。这个函数有完全相同的问题。
  • @Onturenio 这是一个很棒的小例子。 givemetime.__defaults__ 将根据定义进行评估。
猜你喜欢
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
相关资源
最近更新 更多