为什么Python';的空类和函数用作任意数据容器,而不是其他对象?
我见过两个不同的Python对象用于将任意数据分组在一起:空类和函数为什么Python';的空类和函数用作任意数据容器,而不是其他对象?,python,Python,我见过两个不同的Python对象用于将任意数据分组在一起:空类和函数 def struct(): pass record = struct record.number = 3 record.name = "Zoe" class Struct: pass record = Struct() record.number = 3 record.name = "Zoe" 即使类不是空的,只要在运行时定义它,它似乎就可以工作 但是,当我骄傲地试图用内置函数或类来实现这一点时,它就
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'
解释这种行为的内置类和“自定义”类和函数之间有根本区别吗?一些内置类可能更具限制性。此外,用插槽实现的类也不会接受任意属性。内置类型是用C编写的,不能这样修改。但是在py2.2中引入属性之后,您现在可以从内置类型继承并重写或向该子类添加您自己的属性 您可以使用包向内置类型添加属性: 这个项目的目的是让你在测试中找到天堂,但是 如果在生产代码中使用它,可能会导致您陷入地狱
当然,如果你足够自信,那么你可以用C语言创建你自己的类型,并在其中添加这样的特性。如果你想在自己的类中得到一些模拟保护,你可以使用
\uu setattr\uuuuuuuuuu()
方法
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
不同之处在于,函数对象和结构对象都具有
\uuu dict\uuu
属性,但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__'
>>def struct():
... 通过
...
>>>记录=结构
>>>record.number=2
>>>结构说明__
{'number':2}
>>>类结构:
... 通过
...
>>>记录=Struct()
>>>记录编号=3
>>>记录__
{'number':3}
>>>记录=设置()
>>>记录__
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“set”对象没有属性“\uu dict\uuu”
>>>战俘__
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“内置函数”或“方法”对象没有属性“\uuu dict\uuu”
您可以使用插槽模拟行为(尽管仅在新样式的类上):
>>类结构带插槽(对象):
... __插槽u=[]
...
>>>record=StructWithSlots()
>>>记录编号=3
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“StructWithSlot”对象没有属性“number”
>>>记录__
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“StructWithSlot”对象没有属性“\uu dict\uuu”
当然可以用C创建一个类型,它可以像那样使用?@delnan,例如对象
类型。深入了解Python源代码可能会很有趣,其中一个是特例-允许或阻止expando对象。@delnan,但我不会将其称为内置类型,因为您正在用C编写自己的类型(它不是来自标准库)。这个问题是关于内置类和自定义类的。我不认为这实际上以任何有用的方式回答了这个问题-有一个比谈论C代码更高层次的答案(这只适用于CPython):可以在define\uuuu dict\uuuu
上设置任意属性的对象,不要。@AshwiniChaudhary用“Python核心开发者”代替“一个”。换句话说,内置类型不会拒绝其他属性,因为它们是用C编写的,它们可以用C编写并接受其他属性。第一个示例中有一个错误:它应该是record=struct
,而不带()
,否则,record
将为None
,下一行将抛出异常。另外,应该注意,使用函数只起作用,因为用户定义的函数只是python中的另一个对象,这意味着您可以指定任意属性。如果函数是空的或不是空的,也与此无关。但是,虽然您可能可以将其用于一些时髦的元/动态编程魔术,但我想不出为什么使用函数作为存储容器比使用类更可取…@l4mpi我认为,如果您想在非本地
之前,在Python2.x中模拟“写入”其封闭范围的闭包,它会很有用。您使用本地函数对象的特殊属性而不是本地变量。哎呀,第一个示例您是对的。祝贺您,您刚刚重新发明了轮子。
>>> 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__'