Если Вы используете Oracle или другую базу данных, которая поддерживает ее, проверьте свои изменения прежде, чем сделать ФИКСАЦИЮ.
Вам необходимо понимать, как работают значения по умолчанию, чтобы использовать их эффективно.
Функции - это объекты. Таким образом, у них есть атрибуты. Итак, если я создам эту функцию:
>>> def f(x, y=[]):
y.append(x)
return y
Я создал объект. Вот его атрибуты:
>>> dir(f)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
'__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__',
'__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
'func_name']
Один из них - func_defaults
. Звучит многообещающе, что там?
>>> f.func_defaults
([],)
Это кортеж, содержащий значения функции по умолчанию. Если значением по умолчанию является объект, кортеж содержит экземпляр этого объекта.
Это приводит к некоторому довольно нелогичному поведению, если вы думаете, что f
добавляет элемент в список, возвращая список, содержащий только этот элемент, если список не предоставлен:
>>> f(1)
[1]
>>> f(2)
[1, 2]
Но если вы знаете что значение по умолчанию - это экземпляр объекта, который хранится в одном из атрибутов функции, это ' гораздо менее противоречиво:
>>> x = f(3)
>>> y = f(4)
>>> x == y
True
>>> x
[1, 2, 3, 4]
>>> x.append(5)
>>> f(6)
[1, 2, 3, 4, 5, 6]
Зная это, ясно, что если вы хотите, чтобы значением по умолчанию для параметра функции был новый список (или любой новый объект), вы не можете просто спрятать экземпляр объекта в func_defaults
. Каждый раз при вызове функции необходимо создавать новый:
>>>def g(x, y=None):
if y==None:
y = []
y.append(x)
return y
Да; параметры по умолчанию оцениваются только в то время, когда функция определена.
Одним из возможных решений могло бы быть использование параметра в качестве класса , а не экземпляра, как
def foo(blah, klass = B):
b = klass()
# etc
вам необходимо сделать следующее:
class A:
def __init__(self, builds=None):
if builds is None:
builds = B()
self.builds = builds
это очень распространенная ошибка, в которой изменяемые параметры используются в качестве аргументов по умолчанию. на SO наверняка куча дураков.