【问题标题】:Subclass allows arbitrary attributes子类允许任意属性
【发布时间】:2020-01-04 02:47:39
【问题描述】:

考虑这段代码:

class testobj( object ): ...

x = testobj()
x.toast = 'toast'
print( x.toast )   # <-- toast

y = object()
y.toast = 'toast'

最后一行产生错误

AttributeError                            Traceback (most recent call last)
<ipython-input-24-873470c47cb3> in <module>()
----> 1 y.toast = 'toast'

AttributeError: 'object' object has no attribute 'toast'

我也试过

class testobj2( object ):
    def __init__( self ):
        super().__init__()

其行为方式相同,允许设置任意属性。

根据我对 Python 中继承的理解,我希望 testobjobject 具有所有相同的行为(所有相同的方法,包括 __setattr__),因为它是一个子类并且没有定义新方法.但是,它不一样,因为上面的代码允许我设置任意属性。为什么会发生这种情况?如何禁止设置任意属性?

【问题讨论】:

  • 什么是toast(来自y.toast = toast)?
  • 您看到的错误与您所描述的无关。如果改成y.toast = "toast" ,错误就变成object object has no attribute toast,这就是问题所在。
  • 对不起,这应该是一个字符串。
  • 对象不会影响动态创建的属性。不管它们是如何相关的(除非你做了一些元魔法)。
  • @BaileyKocin 无意分享任何内容。他只是为两个对象添加了一个新属性。当类为testobj 时允许,当类为object 时不允许。

标签: python inheritance


【解决方案1】:

防止创建属性的一种简单方法是定义__slots__

class A:
  __slots__ = ('a', 'b')

a = A()
a.a = 1
a.b = 2
a.c = 3 # Raises

--

object() 不允许任意属性,但这是对象实例的特殊规则,在继承时会丢失。

【讨论】:

  • 谢谢。为所有类定义 _slots_ 是更 Pythonic,还是让用户有机会分配任意属性?
  • python 开发人员的主要观点是您应该信任您的用户,而__slots__ 仅作为优化提供。就个人而言,我不信任我的用户。
猜你喜欢
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2014-04-14
  • 2014-05-23
  • 2020-05-19
相关资源
最近更新 更多