【问题标题】:The pythonic way to access a class attribute within the class在类中访问类属性的pythonic方法
【发布时间】:2018-11-07 02:36:08
【问题描述】:

我想知道您认为如何从类中的函数访问类属性。我没有在 PEP8 中找到参考资料或关于它的热门问题。例如

class MyClass(object):
    BAR = 1
    def foo(self):
        # Way A:
        print(self.BAR)

        # Way B:
        print(MyClass.BAR)

通过“self”访问似乎是合理的,因为该属性属于同一个类,对于明显的同类引用的密切引用。 另一方面,通过类名本身的访问是清晰的,因为它是静态的,并且使使用的起源清晰,并且由于它与类的 name 配对,因此可以更加清晰。 p>

【问题讨论】:

  • self.BAR 很酷,因为您可以重命名该类并且它仍然有效。缺点是你不能在静态/类方法中使用它。
  • 为什么不self.__class__.BAR? (stackoverflow.com/questions/25577578/…)

标签: python reference class-attribute


【解决方案1】:

explicity命名类名时,您可以防止子类覆盖您的属性。

另一方面,使用 self 可以为您提供这种灵活性。考虑以下代码:

class MyClass(object):
    BAR = 1
    def foo(self):
        # Way A:
        print(self.BAR)

        # Way B:
        print(MyClass.BAR)


class SubClass(MyClass):
    BAR = 2

class SubClass2(MyClass):
    pass

# output
>>> a = SubClass()
>>> a.foo()
2
1
>>> b = SubClass2()
>>> b.foo()
1
1

【讨论】:

    【解决方案2】:

    对于读取而言,使用哪个并不重要 - self.BARMyClass.BAR 在语法上是等效的,除非您有一个类层次结构,其中子类重新定义了 BAR 的值。

    对于写入,它们是不同的。写入self.BAR 将有效地创建一个新变量,该变量是self 对象实例的本地变量,因此从另一个对象实例从self.BAR 读取的任何内容都不会看到修改。这些调试起来可能非常糟糕,因为从代码中看不出应该发生什么,因为它对时间敏感。

    一般来说,对于类变量,如果你想要来自类层次结构中特定级别的特定变量,你真的应该使用MyClass.BAR,或者如果你想要继承安全的东西,你应该使用type(self).BARself.__class__.BAR。这显然是一个类变量,并且避免了上述动态别名在运行时突然出现的问题。使用self 只会带来一些未来很难发现的脆弱性。

    【讨论】:

    • type(self).BAR
    • 然后我希望您的代码使用self.__class__.method(self) 而不是self.method() ?-) 更严重的是:虽然前两段是完美的,但第三段不是pythonic 方式。 Pythoneers 知道实例上未解析的属性将在类中查找,因此 self.BAR 非常清楚。
    • @brunodesthuilliers 这个问题专门针对类变量,而不是方法。方法已经通过 MRO 解析,除了简单的继承之外,您不太可能在运行时重新定义方法。
    • @solidpixel 方法是类变量。
    • 当然,从纯粹的技术角度来看,它们是。从编码风格的角度来看,实际上很少会在运行时动态地覆盖现有的绑定方法(这是非常糟糕的做法),而可写的“普通”类变量在实际代码中可能相当普遍。
    猜你喜欢
    • 2011-07-27
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2011-08-11
    • 2015-04-25
    • 2020-05-09
    • 2023-02-04
    • 1970-01-01
    相关资源
    最近更新 更多