2011-06-01 12 views
39

estoy enseñando una clase pitón en Programación Orientada a Objetos y como estoy cepillado en forma de explicar las clases, vi una definición de clase vacía:pitón objeto de clase vacía

class Employee: 
    pass 

el ejemplo a continuación, continúa para definir un nombre y otros atributos para un objeto de esta clase:

john = Employee() 
john.full_name = "john doe" 

¡muy interesante!

Me pregunto si hay una manera de definir dinámicamente una función para una clase como esta? algo así como:

john.greet() = print 'hello world!' 

esto no funciona en mi intérprete de Python, pero ¿hay otra forma de hacerlo?

+1

Posible? Sí. ¿Una buena idea? Rara vez (fuera de alguna metaprogramación, por supuesto). – delnan

+3

La definición de clase vacía más corta que he visto es de http://www.gossamer-threads.com/lists/python/python/832915#832915: 'Employee = type ('Employee',(), {})' y luego 'john = Employee()' etc. – eudoxos

Respuesta

30

Una clase es más o menos un envoltorio de lujo para un dict de atributos a los objetos Al crear una instancia de una clase. puede asignar a sus atributos, y los que se almacenarán en foo.__dict__, del mismo modo, se puede ver en foo.__dict__ para cualquier atributo que ya han escrito

Esto significa que puede hacer algunas cosas dinámicas ordenadas como:

class Employee: pass 
def foo(self): pass 
Employee.foo = foo 
.

, así como la asignación a una instancia particular. (EDIT: añadido self parámetro)

+7

Su ejemplo no funcionará como se esperaba: 'john.foo()' levantará un 'TypeError', porque no hay un' parámetro self'. Poner una función en una clase lo convierte en un método, por lo que debe tomar un 'self'. Por otro lado, si asigna una función a una instancia, sigue siendo una función y no tiene acceso a la instancia 'self', que generalmente no es útil. –

+0

@Jochen: usted es, por supuesto, correcto. ¡Ejército de reserva! Para el OP: ¡probablemente te ayude si entiendes lo que salió mal y por qué lo soluciona! – katrielalex

+0

@Jochen, gracias por agregar algo de color a esto. qué tan importante/útil es el acceso a un "yo" si la función que se está definiendo es solo específica del objeto (creo). En otras palabras, esta función no se está definiendo para todos los objetos de tipo Empleado (a menos que use el ejemplo de @ katrielalex y lo defina usando Nombre de clase), pero solo para la instancia de la clase (como en mi ejemplo "john" en el OP) – Ramy

15

Pruebe con lambda:

john.greet = lambda : print('hello world!') 

El que va a ser capaz de hacer:

john.greet() 

EDITAR: Gracias Thomas K para la nota - esto funciona en Python 3.2 y no para Python2, donde print parece ser statement . Pero esto funcionará para lambda s, sin declaraciones (derecha siento, sé que sólo se python3.2 (?)

+1

Esto realmente no funciona: lambdas no puede contener declaraciones. – katrielalex

+0

@katrielalex - Funciona perfecto en mi Python 3.2 (con paréntesis añadidos para 'imprimir', por supuesto). ¿Qué statemets? –

+0

no funciona en PRE python 3.x aparentemente – Ramy

0

usted podría utilizar AttrDict

>>> from attrdict import AttrDict 
>>> my_object = AttrDict() 
>>> my_object.my_attribute = 'blah' 
>>> print my_object.my_attribute 
blah 
>>> 

Instalar attrdict de PyPI:

pip install attrdict 

Es útil en otras situaciones también - como cuando se necesitan atribuir acceso a las claves de diccionario .

0

También podría usar "tuplas con nombre" del módulo estándar collection. Las tuplas con nombre funcionan como tuplas "ordinarias" pero los elementos tienen nombres y puede acceder a los elementos usando la "sintaxis de punto". Del collection docs:

>>> # Basic example 
>>> Point = namedtuple('Point', ['x', 'y']) 
>>> p = Point(11, y=22)  # instantiate with positional or keyword arguments 
>>> p[0] + p[1]    # indexable like the plain tuple (11, 22) 
33 
>>> x, y = p    # unpack like a regular tuple 
>>> x, y 
(11, 22) 
>>> p.x + p.y    # fields also accessible by name 
33 
>>> p      # readable __repr__ with a name=value style 
Point(x=11, y=22)