繁体   English   中英

NameError:函数定义与python中的类/字典定义

[英]NameError: function definitions vs. class/dictionary definitions in python

更新资料

感谢@jwodder在下面的回复,这对我来说逐渐变得清晰起来。

这是一个简化的示例,仍然让我感到困惑:

在函数定义中引用随后定义的变量的情况下,此方法运行良好:

#module.py
def function_scope():
    var = global_var
    return var

def print_global():
    var = function_scope()
    print var

global_var = "Here I am!"

#shell:
>>> from module import print_global
>>> print_global()
Here I am!

但这在类定义中引用了变量的情况下失败了:

#module.py
class ClassScope():
  var = global_var

def print_global():
  var = ClassScope.var
  print var

global_var = "Here I am!"

#shell
>>> from module import print_global
NameError: name 'global_var' is not defined

这意味着在导入时将“执行” class ClassScope()定义。 相比之下,在def function_scope()时(即,后导入,因此该函数可以访问模块的整个全局范围),将“执行” def function_scope()定义。

  1. 我总体上是否在正确考虑? “执行”函数/类定义的概念对我来说似乎很奇怪。
  2. 为什么函数定义和类定义之间存在差异?
  3. 有没有一种方法可以推迟执行类定义,即使其表现得像一个函数,从而使它可以访问成功导入后将存在的整个模块范围?

再次感谢。

原始问题

我最初试图实现一个接受类名并返回该类对象的函数。 但是一路上我意识到我对属性范围并不掌握。 (或者问题可能是可变寿命 ?)

为什么下面的工作...

#module.py
def create_object(class_name):
    classes = {
        'ClassA':ClassA,
    }
    return classes[class_name]()

class ClassA(object):
    pass

#script.py
from module import create_object
obj = create_object('ClassA')

...但这失败了吗?

#module.py
CLASSES = {
    'ClassA':ClassA,
}

def create_object(class_name):
    return CLASSES[class_name]()

class ClassA(object):
    pass 

#script.py
from module import create_object
obj = create_object('ClassA')

这是例外:

Traceback (most recent call last):
  File "script.py", line 2, in <module>
    from module import create_object
  File ".../module.py", line 3, in <module>
    'ClassA':ClassA,
NameError: name 'ClassA' is not defined

看起来ClassA不在范围内,因为第二个示例在CLASSES词典中对其进行了引用。 但是,如果是这种情况,为什么在第一个示例中可以在create_object()中看到它?

非常感谢您对此有所帮助。 非常感谢!

这与发生名称查找而不是范围有关。 当执行使用标识符的代码时,Python仅尝试将标识符与对象或类相关联。 在第一个代码段,该名称ClassAcreate_object仅被分配一个时意思create_object()通过该时间被执行, class ClassA创建定义ClassA已经被执行。 在第二代码片段,您要执行的是指代码ClassAClassA ,甚至被定义,从而创造一个错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM