gpt4 book ai didi

python - 函数参数名称中的类与嵌套类属性冲突

转载 作者:太空宇宙 更新时间:2023-11-04 08:28:35 24 4
gpt4 key购买 nike

考虑这段代码:

def gee(bool_, int32, int64, str_):

class S:
bool_ = bool_
int32 = int32
int64 = int64
str_ = str_

return S

gee(1, 2, 3, 4)

运行会报错:

Traceback (most recent call last):
File "test_.py", line 36, in <module>
gee(1, 2, 3, 4)
File "test_.py", line 27, in gee
class S:
File "test_.py", line 28, in S
bool_ = bool_
NameError: name 'bool_' is not defined

我不知道哪些范围/关闭规则适用于此。 nonlocal 修复了错误,但结果不是我所期望的:

def gee(bool_, int32, int64, str_):

class S:
nonlocal bool_, int32, int64, str_
bool_ = None
int32 = None
int64 = None
str_ = None
print(bool_, int32, int64, str_ )

return S

g = gee(1, 2, 3, 4)
g.bool_

输出:

None None None None
Traceback (most recent call last):
File "test_.py", line 38, in <module>
g.bool_
AttributeError: type object 'S' has no attribute 'bool_'

除了重命名,我还能做些什么来使第一个代码片段中的分配工作?为什么它会这样?因为有name = ...?为什么 Python 不在赋值前计算名称?

最佳答案

当类被编译时,使用与函数类似的规则来解析名称。因为类主体包含对 bool_ 变量的赋值,解释器将其视为类变量,因此当被要求在赋值右侧解析其值时,会在类命名空间中查找。

一种可能性是使它们成为实例变量,在 __init__ 方法中分配,将参数默认为调用 gee 时提供的值:

def gee(bool_, int32, int64, str_):

class S:
def __init__(self, bool_=bool_, int32=int32, int64=int64, str_=str_):
self.bool_ = bool_
self.int32 = int32
self.int64 = int64
self.str_ = str_

return S

my_class = gee(1, 2, 3, 4)
my_instance = my_class()

print(my_instance.bool_)

您应该会发现此代码打印出 1。这是可能的原因是命名参数使用标准(词法)范围规则解析值表达式,而参数名称本身在每次调用开始时被注入(inject)命名空间。

如果您改为使用以下形式的赋值将值绑定(bind)到类变量,您会发现代码也有效

S.bool_ = bool_

因为,在 __init__ 方法运行时,类名 S 已经绑定(bind)到词法封闭的命名空间中。即使值绑定(bind)到类,它们也可以相对于实例进行引用 - 因为它们不存在于那里,所以解释器会继续在实例的类中查找。

然而,无论哪种情况,都需要调用类来设置 __init__ 中的属性值。

关于python - 函数参数名称中的类与嵌套类属性冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54771031/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com