2009-09-30 24 views
42

Muy sencillo, estoy aprendiendo python y no puedo encontrar una referencia que me dice cómo escribir lo siguiente:Cómo definir una clase en Python

public class Team { 
    private String name; 
    private String logo; 
    private int members; 

    public Team(){} 

    // getters/setters 
} 

después:

Team team = new Team(); 
team.setName("Oscar"); 
team.setLogo("http://...."); 
team.setMembers(10); 

que es un equipo de clase con las propiedades: nombre/logo/miembros

Editar Después de un intento de unos pocos que consiguió este:

class Team: 
    pass 

tarde

team = Team() 
team.name="Oscar" 
team.logo="http://..." 
team.members=10 

es esta la forma de pitón ?? Se siente extraño (que viene de un lenguaje fuertemente tipado por supuesto)

+0

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

+0

@steveha: Tal vez, aunque mi verdadera pregunta era, ¿cómo escribo esto en Python ... qué pasa con ... – OscarRyz

Respuesta

43
class Team: 
    def __init__(self): 
    self.name = None 
    self.logo = None 
    self.members = 0 

En Python, que normalmente no se escribe captadores y definidores, a menos que realmente tiene una aplicación no trivial para ellos (momento en el que se utiliza la propiedad descriptores).

+0

Martin, ¿cuál es la diferencia entre mi búsqueda ** equipo de clase: pase ** y tu muestra? – OscarRyz

+2

Puede agregar atributos dinámicamente como desee, pero si la clase Team siempre contendrá esos atributos, es más claro definirlos dentro de la clase y no externamente. – monkut

+1

Es útil para la documentación, ya que permite a las personas que miran a su clase ver qué atributos son útiles. –

98

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.

+0

Y si desea que los valores predeterminados de las cadenas sean "" en lugar de Ninguno, puede hacer ese cambio en la función __init __(). – steveha

+0

+1 Interesante: Si se usan los parámetros nombrados, no obtendré el mensaje de error "método __init__ utiliza exactamente 4 parámetros usados ​​0". ... – OscarRyz

+8

+1: nuevas clases de estilo –

Cuestiones relacionadas