我见过两个不同的Python对象用于将任意数据分组在一起:空类和函数。
def struct():
pass
record = struct
record.number = 3
record.name = "Zoe"
class Struct:
pass
record = Struct()
record.number = 3
record.name = "Zoe"
即使类不是空的,只要它是在运行时定义的,它似乎就可以工作。
但是当我变得自大并尝试用内置函数或类来做这件事时,它就不能工作了。
record = set()
record.number = 3
AttributeError: 'set' object has no attribute 'number'
record = pow
pow.number = 3
AttributeError: 'builtin_function_or_method' object has no attribute 'number'
解释这种行为的内置类和“自定义”类和函数之间是否有根本区别?
发布于 2013-07-11 22:32:17
不同之处在于函数对象和结构对象都有__dict__
属性,而set
实例和内置函数则没有:
>>> def struct():
... pass
...
>>> record = struct
>>> record.number = 2
>>> struct.__dict__
{'number': 2}
>>> class Struct:
... pass
...
>>> record = Struct()
>>> record.number = 3
>>> record.__dict__
{'number': 3}
>>> record=set()
>>> record.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'set' object has no attribute '__dict__'
>>> pow.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__dict__'
在类中,您可以使用插槽模拟行为(尽管只在新样式的类上):
>>> class StructWithSlots(object):
... __slots__ = []
...
>>> record = StructWithSlots()
>>> record.number = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'StructWithSlots' object has no attribute 'number'
>>> record.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'StructWithSlots' object has no attribute '__dict__'
发布于 2013-07-11 21:55:36
一些内置的可能会有更多的限制。此外,使用插槽实现的类也不接受任意属性。
发布于 2013-07-11 22:23:13
如果您希望在自己的类中提供一些模拟保护,则可以使用__setattr__()
方法。
class TestClass(object):
# Accept the attributes in this list
__valid_attributes = ["myattr1", "myattr2"]
def __setattr__(self, name, value):
if not name in TestClass.__valid_attributes:
raise AttributeError(
"{0} has no attribute '{1}'".format(self.__class__.__name__, name))
self.__dict__[name] = value
现在你可以这样做了:
t = TestClass()
t.noattr = "test" # AttributeError: TestClass has no attribute 'noattr'
但是仍然可以设置“有效属性”:
t = TestClass()
t.myattr1 = "test"
print(t.myattr1) # test
https://stackoverflow.com/questions/17595296
复制相似问题