导入具有 Class 定义的 python 模块时出现意外行为
Unexpected behavior while importing python Modules with Class Definitions
考虑文件中的代码my_module.py:
class A(object):
def __init__(self, x=er()):
self.x = x
现在,当我导入这个模块时
import my_module
我收到一个错误,
name 'er is not defined
虽然我知道 my_module 没有定义 er
,但我从来没有创建 class A
的实例。因此,令人费解的是 python 在简单地导入模块时试图执行 __init__
回调。虽然,__init__
调用并未完全执行,如下例所示:
class A(object):
def __init__(self, x=5):
self.x = x
print ('I am here')
现在,当我导入模块时 - 没有打印任何内容,这是预期的行为。
我很疑惑为什么第一个例子中我没有实例化class A
的对象时调用了函数er
。任何指向解释这个的文档的指针?
因为在 Python 中,默认参数值在 定义时间 计算。参见,例如这个 question, or this notorious question。
这已记录在案 here
The default values are evaluated at the point of function definition
in the defining scope, so that
i = 5
def f(arg=i):
print(arg)
i = 6
f()
will print 5.
Important warning: The default value is evaluated only once. This
makes a difference when the default is a mutable object such as a
list, dictionary, or instances of most classes. For example, the
following function accumulates the arguments passed to it on
subsequent calls:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
This will print
[1]
[1, 2]
[1, 2, 3]
If you don’t want the default to be shared between subsequent calls,
you can write the function like this instead:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
考虑文件中的代码my_module.py:
class A(object):
def __init__(self, x=er()):
self.x = x
现在,当我导入这个模块时
import my_module
我收到一个错误,
name 'er is not defined
虽然我知道 my_module 没有定义 er
,但我从来没有创建 class A
的实例。因此,令人费解的是 python 在简单地导入模块时试图执行 __init__
回调。虽然,__init__
调用并未完全执行,如下例所示:
class A(object):
def __init__(self, x=5):
self.x = x
print ('I am here')
现在,当我导入模块时 - 没有打印任何内容,这是预期的行为。
我很疑惑为什么第一个例子中我没有实例化class A
的对象时调用了函数er
。任何指向解释这个的文档的指针?
因为在 Python 中,默认参数值在 定义时间 计算。参见,例如这个 question, or this notorious question。
这已记录在案 here
The default values are evaluated at the point of function definition in the defining scope, so that
i = 5 def f(arg=i): print(arg) i = 6
f()
will print 5.Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:
def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3))
This will print
[1] [1, 2] [1, 2, 3]
If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:
def f(a, L=None): if L is None: L = [] L.append(a) return L