persona - instancias python
Cómo definir una clase en Python (2)
Esto es lo que 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) Declaré que el equipo hereda del object
. Esto hace que Team sea una "clase de nuevo estilo"; esta práctica recomendada en Python desde su introducción en Python 2.2. (En Python 3.0 y superior, las clases siempre son de "nuevo estilo" incluso si se omite la notación (object)
; pero tener esa notación no hace daño y hace que la herencia sea explícita).
1) No es obligatorio, 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 se nombran, por lo que puede proporcionar valores como parámetros posicionales (como con el team
) o puede usar el argument=
forma como lo hice con team3
. Cuando especifica explícitamente el nombre de los argumentos, puede especificar los argumentos en cualquier orden.
2) Si necesita tener funciones de captador y definidor, tal vez 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 propiedad". 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 se pueden agregar los descriptores de propiedades si los necesita. (Y si nunca los necesitas, entonces tu código está menos saturado y te tomó menos tiempo para escribir. ¡Bonificación!)
Aquí hay un buen enlace sobre los descriptores de propiedades:
3) Realmente no importa si especifica valores como parte de la llamada a Team()
o si los introduce en su instancia de clase más adelante. La instancia de clase final con la que terminará 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 se imprimirá True
. (Puede sobrecargar fácilmente el operador ==
para las instancias del Team
y hacer que Python haga lo correcto cuando dice team == team2
pero esto no sucede de manera predeterminada).
EDITAR: Dejé fuera una cosa en la respuesta anterior, y me gustaría agregarla ahora. Si realiza el argumento opcional en la función __init__()
, debe tener cuidado si desea proporcionar un "mutable" como un argumento opcional.
Los enteros y las cadenas son "inmutables". Nunca puedes cambiarlos en su lugar; lo que sucede en cambio es que Python crea un nuevo objeto y reemplaza al que tenías antes.
Las listas y los diccionarios son "mutables". Puedes mantener el mismo objeto por siempre, agregándolo y eliminándolo.
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
La clave que debe saber: los argumentos opcionales se evalúan solo una vez, cuando se compila la función. Entonces, si pasa un objeto mutable como argumento opcional en __init__()
para su clase, entonces cada instancia de su clase comparte un objeto mutable. Esto es casi nunca 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 simple:
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 usar un valor de argumento predeterminado de None
, luego probar que el argumento pasado is None
, califica como un patrón de diseño de Python, o al menos un idioma que debe dominar.
Muy simple, estoy aprendiendo python y no puedo encontrar una referencia que me diga cómo escribir lo siguiente:
public class Team {
private String name;
private String logo;
private int members;
public Team(){}
// getters/setters
}
Luego:
Team team = new Team();
team.setName( "Oscar" );
team.setLogo( "http://...." );
team.setMembers( 10 );
Ese es un equipo de clase con las propiedades: nombre / logo / miembros
Editar Después de algunos intentos conseguí esto:
class Team:
pass
Luego
team = Team()
team.name="Oscar"
team.logo="http://..."
team.members=10
¿Es esta la manera de los pitones? Se siente extraño (viene de un lenguaje fuertemente tipado, por supuesto)
class Team:
def __init__(self):
self.name = None
self.logo = None
self.members = 0
En Python, normalmente no se escriben captadores y definidores, a menos que realmente tenga una implementación no trivial para ellos (en ese momento se usan los descriptores de propiedad).