2010-03-26 15 views
13

estoy escribiendo una clase para insertar a los usuarios en una base de datos, y antes de llegar demasiado lejos en, sólo quiero para asegurarse de que mi enfoque OO está limpio:manera adecuada para establecer las variables de instancia de objeto

class User(object): 

    def setName(self,name): 

     #Do sanity checks on name 
     self._name = name 

    def setPassword(self,password): 

     #Check password length > 6 characters 
     #Encrypt to md5 
     self._password = password 

    def commit(self): 

     #Commit to database 

>>u = User() 
>>u.setName('Jason Martinez') 
>>u.setPassword('linebreak') 
>>u.commit() 

¿Es este el enfoque correcto? ¿Debo declarar las variables de clase arriba? ¿Debo usar un _ en frente de todas las variables de clase para hacerlas privadas?

Gracias por ayudarnos.

+0

No hay variables de clase en su código. Considera actualizar tu título. –

+0

Qué tutorial estás usando para aprender Python. Esto debe estar cubierto. Como no es así, me gustaría saber qué tutorial estás usando. –

+0

"variables de instancia de objeto" se llaman "atributos" en Python –

Respuesta

19

Por lo general es correcta, que yo sepa, pero se puede limpiarlo con properties.

class User(object): 

    def _setName(self, name=None): 
     self._name = name 

    def _getName(self): 
     return self._name 

    def _setPassword(self, password): 
     self._password = password 

    def _getPassword(self): 
     return self._password 

    def commit(self): 
     pass 

    name = property(_getName, _setName) 
    password = property(_getPassword, _setPassword) 

>>u = User() 
>>u.name = 'Jason Martinez' 
>>u.password = 'linebreak' 
>>u.commit() 

También hay una conveniente sintaxis basada en el decorador, los documentos explican eso también.

+0

Esto fue realmente útil. Gracias. – ensnare

+1

Noté que su constructor aceptó un argumento obligatorio de 'nombre', por lo que su uso de ejemplo de 'Usuario()' arrojaría un error. Edité mi ejemplo para poner por defecto el 'nombre' en' Ninguno' para evitar esto, pero es posible que desee proporcionar una implementación sobrecargada sin argumentos. – bcherry

+0

¡Sí, gracias! – ensnare

3

No hay variables de clase en ese código, solo atributos de instancia. Y use properties en lugar de accesos. Y sí crean los atributos de instancia en el inicializador, preferiblemente de valores pasados ​​en:

class User(object): 
    def __init__(self, name, password='!!'): 
    self.name = name 
    self.password = password 

    ... 
+0

Gracias por la respuesta. No estoy seguro de qué propiedades son, pero leeré. El objeto Usuario tiene muchas variables, 50 o más, así que creo que serían demasiadas para pasar al constructor, ¿no? Sé que actualmente no hay variables de clase en el código. Lo que quiero decir es, ¿debería hacer estas variables de clase? Gracias. – ensnare

+0

Nunca, nunca use variables de clase cuando el valor necesite variar de una instancia a otra. –

7

usando una sola _ no hace que sus atributos sean privados: es una convención que dice que es un atributo interno y no debe accederse en circunstancias normales mediante un código externo. Con su código también significa que la contraseña y el nombre son de solo lectura.

Sugiero usar un inicializador para su clase que inicialice sus atributos, incluso a un valor predeterminado como Ninguno: le facilitará las cosas en su método de compromiso donde no tendrá que verificar la existencia de los atributos _name y _password (con hasattr).

Usa Pylint en tu código.

2

Otros ya lo señalaron: evite usar setters y getters y use el acceso de atributo simple si no necesita realizar una lógica adicional al obtener/configurar su atributo. Si necesita esa lógica adicional, entonces use propiedades.

Si usted tiene muchos parámetros para pasar a un inicializador ejemplo, considerar el uso de objeto independiente o diccionario que sostiene todos los parámetros:

>>> class User(object): 
...  def __init__(self, params): 
...   self.__dict__.update(params) 
... 

>>> params = { 
...  'username': 'john', 
...  'password': 'linebreak', 
...  } 
>>> user = User(params) 
>>> user.username 
'john' 
>>> user.password 
'linebreak' 

P. S. En su caso, no necesita declarar sus atributos en el nivel de clase. Por lo general se hace eso, si desea compartir el mismo valor en todas las instancias de la clase:

>>> class User(object): 
...  type = 'superuser' 
... 
>>> user = User() 
>>> user2 = User() 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'superuser' 
>>> 
>>> user2.type = 'instance superuser' 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'instance superuser' 
>>> User.type 
'superuser' 
Cuestiones relacionadas