让我简单解释一下这个问题:
这是一个示例代码:
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
new_name = base_func.common_consts.name #this is where the problem occurs
def get_result(self):
self.validate()
self.execute()
所以当我尝试使用base_func中的common_consts时,在func1.consts中,我收到以下错误:
NameError:未定义全局名称“base_func”
我不知道为什么会这样。有人可以帮忙吗?
python中的嵌套范围是否有限制,尤其是2.7
此外,如果我删除顶级服务器类,并将功能类作为独立类,一切似乎都可以正常工作。工作代码的示例如下:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
new_name = base_func.common_consts.name #this is where the problem occurs
def get_result(self):
self.validate()
self.execute()
这让我相信python中的嵌套深度和命名空间范围肯定存在一些限制。在改变我的设计之前,我只想确定一下。
答案 0 :(得分:2)
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
# base_func and func1 are at same, level. So, here you can directly use base_func and func1 anywhere
# at top level of the server class
class func1(base_func):
class consts:
new_name = base_func.common_consts.name # this is where the problem occurs
def get_result(self):
self.validate()
self.execute
对于一个类(类有自己的命名空间),变量查找的工作方式如下:
在解析类体时,可以直接访问类体内定义的任何变量,但只能访问一次 它被解析成为一个类属性。
因为,类base_func
位于server
类中,仍在解析func1(base_func)
将正常工作。
但是,对于课程consts
base_func
并不是同一级别。因此,在查看其体内的变量后,它将直接跳跃
到它的封闭范围,即在这种情况下的全局命名空间。
修复将是这样的分配:
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
pass
def get_result(self):
self.validate()
self.execute
func1.consts.new_name = base_func.common_consts.name
答案 1 :(得分:0)
你遇到了课程范围的问题。除了直接出现在类范围内的操作之外,类范围永远不可用。这就是为什么你不能在没有引用self的情况下在另一个方法中调用方法的原因。
例如
class A(object):
def f(self):
pass
def g(self):
f() # error, class scope isn't available
创建嵌套类时也是如此。初始类语句class ClassName(Base):
可以访问类范围,但是一旦在嵌套类范围内,您将无法访问封闭类范围。
通常,没有充分的理由在python中嵌套类。您应该尝试在模块级别创建所有类。您可以通过将内部类放在子模块中或者使用下划线为它们添加前缀来隐藏内部类。
class _BaseFunctionality(object):
# common constants
name = "name"
value = "value"
def execute(self):
return (self.name, self.value)
class _SpecificFunctionality(_BaseFunctionality):
# specific constants
# override value of value attribute
value = "another_value"
def get_result(self):
assert self.name == "name"
return self.execute()
class Server(object):
functionality = _SpecificFunctionality()
assert _BaseFunctionality.value == "value"
assert _SpecificFunctionality.value == "another_value"
assert Server().functionality.get_result() == ("name", "another_value")