parameter python optional-arguments

parameter - Parámetros opcionales de Python



python add optional parameter (3)

Debe comprender cómo funcionan los valores predeterminados para utilizarlos de manera efectiva.

Las funciones son objetos. Como tales, tienen atributos. Entonces, si creo esta función:

>>> def f(x, y=[]): y.append(x) return y

He creado un objeto. Aquí están sus atributos:

>>> 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'']

Uno de ellos es func_defaults . Eso suena prometedor, ¿qué hay ahí?

>>> f.func_defaults ([],)

Esa es una tupla que contiene los valores predeterminados de la función. Si un valor predeterminado es un objeto, la tupla contiene una instancia de ese objeto.

Esto conduce a un comportamiento bastante contrario a la intuición si está pensando que f agrega un elemento a una lista, devolviendo una lista que contiene solo ese elemento si no se proporciona una lista:

>>> f(1) [1] >>> f(2) [1, 2]

Pero si sabe que el valor predeterminado es una instancia de objeto que se almacena en uno de los atributos de la función, es mucho menos contradictorio:

>>> 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]

Sabiendo esto, está claro que si desea que un valor predeterminado del parámetro de una función sea una nueva lista (o cualquier objeto nuevo), no puede simplemente ocultar una instancia del objeto en func_defaults . Debe crear uno nuevo cada vez que se llame a la función:

>>>def g(x, y=None): if y==None: y = [] y.append(x) return y

Chicos, acabo de comenzar python recientemente y me confunden con los parámetros opcionales, digamos que tengo el programa así:

class B: pass class A: def __init__(self, builds = B()): self.builds = builds

Si creo A dos veces

b = A() c = A()

e imprimir sus compilaciones

print b.builds print c.builds

Descubrí que están usando exactamente el mismo objeto,

<__main__.B instance at 0x68ee0> <__main__.B instance at 0x68ee0>

Pero no es lo que quiero, ya que si b cambia algún estado interno de compilaciones, el objeto en c también se cambiará.

¿Es posible recrear estos parámetros opcionales cada vez usando esta sintaxis de parámetros opcionales?


Necesitas hacer lo siguiente:

class A: def __init__(self, builds=None): if builds is None: builds = B() self.builds = builds

es un error muy extendido, utilizando parámetros mutables como argumentos predeterminados. hay un montón de incautos probablemente en SO.


Sí; los parámetros predeterminados se evalúan solo en el momento en que se define la función.

Una posible solución sería que el parámetro fuera una clase en lugar de una instancia, a la

def foo(blah, klass = B): b = klass() # etc