首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Python的空类和函数可以作为任意数据容器工作,而不是其他对象?

为什么Python的空类和函数可以作为任意数据容器工作,而不是其他对象?
EN

Stack Overflow用户
提问于 2013-07-11 21:54:14
回答 3查看 1.6K关注 0票数 18

我见过两个不同的Python对象用于将任意数据分组在一起:空类和函数。

代码语言:javascript
复制
def struct():
    pass

record = struct
record.number = 3
record.name = "Zoe"


class Struct:
    pass

record = Struct()
record.number = 3
record.name = "Zoe"

即使类不是空的,只要它是在运行时定义的,它似乎就可以工作。

但是当我变得自大并尝试用内置函数或类来做这件事时,它就不能工作了。

代码语言:javascript
复制
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'

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-11 22:32:17

不同之处在于函数对象和结构对象都有__dict__属性,而set实例和内置函数则没有:

代码语言:javascript
复制
>>> 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__'

在类中,您可以使用插槽模拟行为(尽管只在新样式的类上):

代码语言:javascript
复制
>>> 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__'
票数 8
EN

Stack Overflow用户

发布于 2013-07-11 21:55:36

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

票数 2
EN

Stack Overflow用户

发布于 2013-07-11 22:23:13

如果您希望在自己的类中提供一些模拟保护,则可以使用__setattr__()方法。

代码语言:javascript
复制
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

现在你可以这样做了:

代码语言:javascript
复制
t = TestClass()
t.noattr = "test" # AttributeError: TestClass has no attribute 'noattr'

但是仍然可以设置“有效属性”:

代码语言:javascript
复制
t = TestClass()
t.myattr1 = "test"
print(t.myattr1) # test
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17595296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档