python类只读属性(在datetime中)

时间:2018-01-24 21:56:16

标签: python python-3.x oop

我知道将属性设置为私有的快速方法是在属性之前使用__(稍后更正,因为这实际上是名称修改,而不是限制访问 ),或使用@property

但是,我发现对于python标准库模块,例如datetime,这是以不同的方式设置的吗?

要解释我的问题,请转到the source code of datetime

我们以课程timedelta为例:

class timedelta:
    ...
    ...
    ... 

timedelta.min = timedelta(-999999999)
timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59,
                          microseconds=999999)
timedelta.resolution = timedelta(microseconds=1)

类属性是否在类之外设置?为什么吗

如果我:

import datetime
d= datetime.timedelta(days=1, hours=12)
print(d)
print(d.max)  # >>> 999999999 days, 23:59:59.999999
print(type(d.max))  # >>> <class 'datetime.timedelta'>

d.max = 1000  # regardless of the reason, if I just want to do this
# >>> AttributeError: 'datetime.timedelta' object attribute 'max' is read-only

我想知道AttributeError来自哪里?我无法在源代码中的任何地方找到此错误消息?

谢谢!

2 个答案:

答案 0 :(得分:4)

  

类属性是在类之外设置的吗?为什么呢?

正在执行timedelta类的主体时,

timedelta不存在。您必须在创建类对象之前执行class timedelta:块中的所有代码,并且可以单独使用。

  

我想知道这个AttributeError来自哪里?我在源代码中的任何地方找不到会出现此错误消息?

datetime模块是用纯Python编写的,tries to use是一个更快的模块written in C,如果可以的话。纯Python代码按预期工作:

>>> import sys
>>> sys.modules['_datetime'] = None  # prevent the C module from loading
>>> from datetime import timedelta
>>> timedelta.min = 5
>>> timedelta.min
5

timedelta班级tp_flags设置为Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE。您只能设置包含Py_TPFLAGS_HEAPTYPE flag

的对象的属性

答案 1 :(得分:2)

这不是CPython解释器使用的日期时间模块的源代码。出于性能原因,CPython源在C中实现了许多标准库。它们确实提供了仅支持Python的实现(例如,我认为PyPy在很多情况下都依赖它)。

datetime的源代码实际上就在这里:

https://github.com/python/cpython/blob/3.6/Modules/_datetimemodule.c

访问受限于C级。

注意,双下划线名称修改名称修改,它不会限制访问。