Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Python';的空类和函数用作任意数据容器,而不是其他对象?_Python - Fatal编程技术网

为什么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" 即使类不是空的,只要在运行时定义它,它似乎就可以工作 但是,当我骄傲地试图用内置函数或类来实现这一点时,它就

我见过两个不同的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'

解释这种行为的内置类和“自定义”类和函数之间有根本区别吗?

一些内置类可能更具限制性。此外,用插槽实现的类也不会接受任意属性。

内置类型是用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__'