2017-02-10 4 views
0

Рассмотрим код в файле 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') 

Теперь, когда я импортировать модуль - ничего не печатается, и ожидается, что это поведение.

Я озадачен, почему функция er вызвана в первом примере, когда я не создаю объект class A. Любые указатели на документацию, которая объясняет это?

+0

В любом случае, 'x' не действует как обратный вызов здесь, если это то, что вы имеете в виду. У вас может быть только параметр 'er', а в' __init__' вы можете сделать 'self.x = er()' –

ответ

3

Поскольку в Python значения аргументов по умолчанию оцениваются в времени определения. См. Например, question или this 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