【问题标题】:How to get an attribute just from the current class and not from possible parent classes?如何仅从当前类而不是从可能的父类中获取属性?
【发布时间】:2011-03-18 03:31:57
【问题描述】:

如何仅从当前类而不是从可能的父类中获取属性?如果我使用getattr,它会遍历类层次结构,但如果属性未在当前类中定义(即使它在某些父类中定义),我想获得None

【问题讨论】:

  • 为什么你要同时使用继承来定义类而不是在类中使用继承?这听起来像你犯了一个设计错误。你能提供更多细节吗?
  • 是的,这有点骇人听闻。问题是我必须重用现有的 API,所以我不得不玩丑。但我认为这本身就是一个有效的问题。
  • 这听起来不像“hackish”——听起来很糟糕。您应该使用 Delegation。不是继承。请提供一些您认为您正在尝试做的事情的背景。
  • 我已经发布了最终代码on Django Trac。我制作了一个元类和 mixin 以允许多个 ModelForm 继承。
  • 我也有 posted an answer 在 Stack Overflow 上使用这个元类和 mixin。

标签: python django object


【解决方案1】:

没有什么可以阻止您在初始化 super 后在 init 中“重置”该属性,将其设置为 None(在 Python 中,继承和继承的类是 super 和 sub btw,而不是 parent 和 child)。

除非该属性是在其他地方创建的并且不能保证它的存在,否则只有在这种情况下沿着继承树走,此时您可能会遇到一些严重的设计问题:)

话虽如此,这些都是解决问题的穷人解决方案,我同意您可能需要解决一些设计问题。

【讨论】:

    【解决方案2】:

    你有点用自己的规则把自己描绘成一个角落。听起来更像是设计缺陷,而不是 Python 的语言或类问题,因为 Python 的优点在于消除和隐藏类继承的复杂性。

    您可能需要接受这样的“替代”解决方案:

    class Parent(object):
        property_on_parent = 'default value'
        @property
        def property_accessor(self):
            return self.property_on_parent
    
    class Child(Parent):
        property_on_child = None
        @property
        def property_accessor(self):
            return self.property_on_child
    
    c = Child()
    assert c.property_accessor == None
    

    但是,我觉得你最好重新考虑这种方法。

    【讨论】:

      【解决方案3】:

      这不是 100% 证明的答案(例如,它不适用于使用 __slots__ 的类),但它在大多数情况下都有效:

      >>> class A(object):
      ...    x = 42
      ...    y = 43
      ... 
      >>> class B(A):
      ...    x = 11
      ... 
      >>> b = B()
      

      您可以像这样直接检查该属性是否在类中定义:

      >>> 'x' in b.__class__.__dict__
      True
      >>> 'y' in b.__class__.__dict__
      False
      

      现在回答你的问题:

      # comment explaining why this unusual check is necessary
      if 'attribute' in instance.__class__.__dict__:
          value = instance.attribute
      else:
          value = None
      

      【讨论】:

        猜你喜欢
        • 2015-10-29
        • 1970-01-01
        • 2011-04-23
        • 2015-02-02
        • 1970-01-01
        • 2020-11-12
        • 2019-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多