【问题标题】:Unexpected behavior while importing python Modules with Class Definitions导入具有类定义的 python 模块时出现意外行为
【发布时间】:2017-02-10 00:08:16
【问题描述】:

考虑文件 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。任何指向解释这一点的文档的指针?

【问题讨论】:

  • 无论如何,x 在这里不是作为回调,如果这就是你的意思。你可以有一个参数er,在__init__你可以做self.x = er()

标签: python python-2.7 class python-import


【解决方案1】:

因为在 Python 中,默认参数值在定义时间进行评估。例如,请参见 questionthis notorious question

这是记录在here

默认值在函数定义时进行评估 在定义范围内,因此

i = 5

def f(arg=i):
    print(arg)

i = 6

f() 将打印 5。

重要警告:默认值仅评估一次。这 当默认值是可变对象(例如 大多数类的列表、字典或实例。例如, 以下函数累积传递给它的参数 后续调用:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

这将打印出来

[1]
[1, 2]
[1, 2, 3]

如果您不希望在后续调用之间共享默认值, 你可以这样写函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    相关资源
    最近更新 更多