【问题标题】:Why is a function label in-scope within that function but a class method label is not in-scope within itself?为什么函数标签在该函数范围内,但类方法标签不在其范围内?
【发布时间】:2018-10-18 17:22:03
【问题描述】:

如果func 是一个全局函数,func 可以自己引用它。

def func(y):
    result = func.x + y
    # `func.x` does not raise an errors
    return result   
func.x = 5  

func(100)

但是,类方法似乎不能引用自身:

class K:        
    def mthd(self, y):
        return mthd.x + y
    mthd.x = 5

K.mthd() # raises an exception

引发的异常是NameError:

[Drive Letter]:\[path]
Traceback (most recent call last):
  File "[Path]/[filename].py", line 35, in <module>
    K.mthd()
  File "[Path]/[filename].py", line 40, in mthd
    return mthd.x + y
NameError: name 'mthd' is not defined

Process finished with exit code 1

这是为什么?

是因为"func"globals"mthd"K.__dict__ 中吗?

函数可以引用自身之外的变量,例如:

x = 3
def f():
    print(x)

错误是因为K.mthd 可以访问名称localsglobals,但不能访问K.__dict__

【问题讨论】:

标签: python python-3.x class oop


【解决方案1】:

func 是一个全局名称,mthd 不是。方法是类对象上的一个属性,可作为全局对象:

K.mthd.x

class 主体(套件)本身中,mthd 是本地名称;在class 语句的末尾,所有本地人都被带入了类主体;一旦创建了类,本地名称就不再可用。

来自Class definitions section of the Python reference documentation

类的套件然后在一个新的执行框架[...]中执行,使用一个新创建的本地命名空间和原来的全局命名空间。 (通常,套件主要包含函数定义。)当类的套件完成执行时,它的执行帧被丢弃,但它的本地命名空间被保存。然后使用基类的继承列表和属性字典保存的本地命名空间创建一个类对象。

所以在您的代码中,mthd.x = 5 行类似于在函数体中访问本地变量。就像resultfunc() 函数范围之外不可用一样,mthd 在类创建期间可用的命名空间之外不可用。

class 套件可以引用全局变量就好了,方法也可以:

>>> x = 42
>>> class Demo:
...     print('Class body, globals are available, like x =', x)
...     def method(self):
...         print('Method body, globals are available, like x =', x)
...
Class body, globals are available, like x = 42
>>> Demo().method()
Method body, globals are available, like x = 42

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多