【问题标题】:Set attribute on class but not on instances在类而不是实例上设置属性
【发布时间】:2017-08-17 06:59:42
【问题描述】:

我在 Python 中创建了一些自定义类,我想知道是否有任何方法可以在一个类上定义一个属性而不让其所有实例都继承该属性。

例如:

class Foo():
    def bar():
        pass

Foo.bar # would return `bar` function
instanceOfFoo = Foo()
instanceOfFoo.bar # would raise an AttributeError

我知道我可以继承Foo,覆盖bar,并手动将AttributeError 提升为@property,以提供bar 不存在的“外观”,但是有什么办法可以这样做没有子类?

上下文:我正在尝试从 JavaScript 复制 Date 类,其中调用 Date.parse(在 Date 类本身上)会做一些事情,但在 Date 实例上调用 parse 不会做任何事情,因为实例不会从Date 继承parse 函数。 (它们从 Date.prototype 继承了所有属性,这就是它在那里工作的原因。)

【问题讨论】:

  • @Klaus D. 类方法仍然由类的实例继承。他们只是收到了类作为他们的第一个参数,而不是类的实例。我正在寻找一种方法来防止实例完全继承类的属性。
  • 好吧,你要么继承,要么不继承。一般来说,试图用另一种非常不同的语言模仿一种语言是有问题的。
  • 没有办法阻止您的实例继承类方法。一个可能的“肮脏”解决方法可能是在您的函数栏中,您可以检查您是否将实例作为第一个参数,然后可以引发 AttributeError 或在您的 init 函数中,您可以删除该栏函数属性.
  • @ChristianFigueroa 在 init 内部,而不是删除该属性,尝试使用某些东西(可能会引发异常)对其进行初始化,这可能是您所有此类的常见调用案例。或者只是尝试设置 self.bar = None。这会奏效。

标签: python class inheritance attributes


【解决方案1】:

我使用元类找到了我想要的东西。

class MetaFoo(type):
    def bar(self):
        pass

class Foo(metaclasses=MetaFoo):
    pass

Foo.bar # returns `bar` method
instanceOfFoo = Foo()
instanceOfFoo.bar # raises AttributeError

Foo 正在使用MetaFoo 类创建,并在此过程中继承bar 方法。由于继承仅适用于类的直接实例,FooMetaFoo 的实例)继承 bar 方法,但 instanceOfFooFoo 的实例但不是 MetaFoo)不继承方法。

【讨论】:

    【解决方案2】:

    您的问题有一种解决方法。请注意,在python 中,您不能调用Foo.bar(),除非bar() 被声明为@staticmethod@classmethod

    class Foo(object):
        def __init__(self):
            self.bar = self.foo
    
        @classmethod
        def bar(cls):
            return 1
    
        @classmethod
        def foo(cls):
            raise AttributeError("Method not implemented for instances of a class.")
    
    print(Foo.bar()) # --> 1
    t = Foo()
    print(t.bar())   # --> AttributeError: Method not implemented for instances of a class.
    

    【讨论】:

      猜你喜欢
      • 2014-12-07
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 2010-12-04
      • 2020-07-26
      • 1970-01-01
      • 2022-06-15
      相关资源
      最近更新 更多