python - 如何在 Python 中的类中引用静态属性?

标签 python class constructor

我有以下 python 代码片段:

class myClass:
    myVar = 'a'

    def __init__(self):
        self.myOtherVar = 'b'
        myVar = 'c'  # Gets assigned but only as a local variable.

    print myVar            # prints 'a' !
    print self.myOtherVar  # says 'self' not found

我的问题是这样的; 从 myClass 中打印 myVar 的内容和/或从 init 重新分配它们的正确方法是什么?

最佳答案

您面临的问题是因为您不了解类声明的作用域是如何工作的。类声明在其自己的范围内执行。执行完成后,会创建一个新的类对象,并将获得的作用域作为其 __dict__ 附加到该类。

注意:类范围不能从方法范围内搜索!这意味着当方法定义中时,您必须将类属性引用为MyClass.attribute

例如:

class MyClass:
    var = 1

    # we are executing this code as a single block
    # so you must reference the variable as is usual
    print(var)

    # default values are *not* inside the definition.
    # they are evaluated in the outer scope, so use plain "var" here
    def method(self, a_default=var):
        print(a_default)

    def other_method(self):

        # inside methods you are in a different scope
        print(MyClass.var)

        # equivalent *if* no "var" instance attributes exists
        print(self.var)

注意:由于在执行其声明时该类已不存在,因此您不能MyClass 的“顶层”引用 MyClass > 声明:

class MyClass:
    var = 1
    print(MyClass.var)   # error: MyClass still doesn't exist.
<小时/>

这样做的副作用是以下代码:

class MyClass:
    x = 1
    results = list(i+x for i in range(10))

产品:

NameError                                 Traceback (most recent call last)
<ipython-input-6-f1d4417b2e52> in <module>()
----> 1 class MyClass:
      2     x = 1
      3     results = list(i+x for i in range(10))
      4 

<ipython-input-6-f1d4417b2e52> in MyClass()
      1 class MyClass:
      2     x = 1
----> 3     results = list(i+x for i in range(10))
      4 

<ipython-input-6-f1d4417b2e52> in <genexpr>(.0)
      1 class MyClass:
      2     x = 1
----> 3     results = list(i+x for i in range(10))
      4 

NameError: name 'x' is not defined

因为事实上,生成器表达式(以及 python3 中的列表推导式)被视为具有自己作用域的函数。由于未从内部函数作用域中搜索类作用域,因此无法找到 x

您可以使用函数定义和默认值来解决这个问题:

class MyClass:
    x = 1
    def _make_results(x=x):
        return list(i+x for i in range(10))
    results = _make_results()
    del _make_results    # otherwise it would be added as a method.
    # or:
    results = (lambda x=x: list(i+x for i in range(10)))()

这通常不是问题,因为类定义很少包含除方法定义和一些常量之外的任何内容。

<小时/>

已经有一些关于类范围的问题:

关于python - 如何在 Python 中的类中引用静态属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24505869/

相关文章:

python - Pygtk 线程化长命令行进程

Python 无法检查某个值是否在列表中

javascript - jQuery every 不适用于某些类或一般类?

constructor - TO 和 MAKE 的目的有何不同,它们记录在何处?

java抽象类,父类(super class)中没有调用构造函数,为什么?

c++ - 在另一个类的构造函数中创建 n 个对象的最佳方法?

python - 使用关键字对列中的文本进行分类

python - 由于 g++ 编译器错误,NS-3 构建失败

android - 将字符串传递给 setContentView?

python - 如何在继承 wx.Frame 的类之外的类中创建 staticBitmap