Aquí es lo que yo recomendaría:
class Team(object):
def __init__(self, name=None, logo=None, members=0):
self.name = name
self.logo = logo
self.members = members
team = Team("Oscar", "http://...", 10)
team2 = Team()
team2.name = "Fred"
team3 = Team(name="Joe", members=10)
Algunas notas sobre esto.
0) He declarado que Team hereda de object
. Esto hace que Team sea una "clase de nuevo estilo"; esto ha sido una práctica recomendada en Python desde que se introdujo en Python 2.2. (En Python 3.0 y superior, las clases siempre son de "estilo nuevo" incluso si omite la notación (object)
, pero tener esa notación no hace daño y hace que la herencia sea explícita.) Aquí hay un StackOverflow discussion de clases de nuevo estilo.
1) No es necesario, pero hice que el inicializador tomara argumentos opcionales para que pueda inicializar la instancia en una línea, como hice con team
y team3
. Estos argumentos son nombrados, por lo que puede proporcionar valores como parámetros posicionales (como con team
) o puede usar el formulario argument=
como lo hice con team3
. Cuando especifica explícitamente el nombre de los argumentos, puede especificar argumentos en cualquier orden.
2) Si necesita tener funciones getter y setter, quizás para verificar algo, en Python puede declarar funciones de método especiales. Esto es lo que Martin v. Löwis quiso decir cuando dijo "descriptores de propiedades". En Python, generalmente se considera una buena práctica simplemente asignar a las variables miembro, y simplemente hacer referencia a ellas para obtenerlas, porque siempre puede agregar los descriptores de propiedad más adelante en caso de que las necesite. (Y si no los necesita, entonces su código es menos desordenada y se tomó menos tiempo para escribir Bono.!)
Aquí hay un buen enlace sobre descriptores de propiedades: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
3) Realmente no si especifica valores como parte de la llamada al Team()
o si los introduce en su instancia de clase más tarde. La instancia final de clase con la que termines será idéntica.
team = Team("Joe", "http://example.com", 1)
team2 = Team()
team2.name = "Joe"
team2.logo = "http://example.com"
team2.members = 1
print team.__dict__ == team2.__dict__
Lo anterior imprimirá True
.(Usted puede fácilmente sobrecargar el operador ==
para Team
casos, Python y hacer lo correcto cuando dice team == team2
pero esto no sucede por defecto.)
EDIT: me he dejado algo en lo que antecede responde, y me gustaría agregarlo ahora. Si realiza el argumento opcional en la función __init__()
, debe tener cuidado si desea proporcionar un "mutable" como argumento opcional.
Los enteros y las cadenas son "inmutables". Nunca puedes cambiarlos en su lugar; lo que sucede en su lugar es que Python crea un nuevo objeto y reemplaza al que tenía antes.
Las listas y los diccionarios son "mutables". Puede mantener el mismo objeto por siempre, agregarlo y eliminarlo.
x = 3 # the name "x" is bound to an integer object with value 3
x += 1 # the name "x" is rebound to a different integer object with value 4
x = [] # the name "x" is bound to an empty list object
x.append(1) # the 1 is appended to the same list x already had
Lo más importante que debe saber: los argumentos opcionales se evalúan solo una vez, cuando se compila la función. Por lo tanto, si pasa un parámetro mutable como argumento opcional en el __init__()
para su clase, cada instancia de su clase comparte un objeto mutable. Esto casi nunca es lo que quieres.
class K(object):
def __init__(self, lst=[]):
self.lst = lst
k0 = K()
k1 = K()
k0.lst.append(1)
print k0.lst # prints "[1]"
print k1.lst # also prints "[1]"
k1.lst.append(2)
print k0.lst # prints "[1, 2]"
La solución es muy sencilla:
class K(object):
def __init__(self, lst=None):
if lst is None:
self.lst = [] # bind lst with a new, empty list
else:
self.lst = lst # bind lst with provided list
k0 = K()
k1 = K()
k0.lst.append(1)
print k0.lst # prints "[1]"
print k1.lst # print "[]"
Este negocio de utilizar un valor de argumento por defecto de None
, luego las pruebas de que el argumento pasado is None
, califica como un patrón de diseño de Python, o por lo menos una idioma que debes dominar.
Me gustaría sugerir que alguien cambie el título a algo que sea mejor para futuras búsquedas. Algo así como "La mejor manera de definir una clase en Python". – steveha
@steveha: Tal vez, aunque mi verdadera pregunta era, ¿cómo escribo esto en Python ... qué pasa con ... – OscarRyz