2012-02-26 9 views
30
class MyClass: 
    def myFunc(self): 
     pass 

¿Puedo crear una salida MyFunc de la definición de clase? Tal vez incluso en otro módulo?¿Python define el método fuera de la definición de la clase?

+1

Sí ... se puede definir una función en la que desea (o casi), pero con qué propósito? ¿Qué quieres lograr? Tenga en cuenta que una función en una clase es diferente de la que está afuera, p., el uso del parámetro auto, que hace referencia a la instancia en que se crea la función en – aweis

+0

Las funciones son demasiado. Y los usuarios pueden agregar más. La "clase" es básicamente un contenedor de útiles funciones auxiliares. –

+0

Parece que está trabajando con herencia, donde una clase contiene una lista de la función "auxiliar". ¡Entonces otra clase puede implementar esta clase y usar las funciones de ella! – aweis

Respuesta

51

Sí. Se puede definir una función fuera de una clase y luego usarlo en el cuerpo de la clase como un método:

def func(self): 
    print "func" 

class MyClass(object): 
    myMethod = func 

También puede agregar una función a una clase después de que ha sido definida:

class MyClass(object): 
    pass 

def func(self): 
    print "func" 

MyClass.myMethod = func 

Puede definir la función y la clase en diferentes módulos si lo desea, pero desaconsejaría definir la clase en un módulo, luego importarlo en otro y agregarle métodos dinámicamente (como en mi segundo ejemplo), porque entonces ' d tienen un comportamiento sorprendentemente diferente de la clase dependiendo de si se ha importado o no otro módulo.

Me gustaría señalar que si bien esto es posible en Python, es un poco inusual. Menciona en un comentario que "los usuarios pueden agregar más" métodos. Eso suena extraño. Si está escribiendo una biblioteca, probablemente no desee que los usuarios de la biblioteca añadan métodos dinámicamente a las clases de la biblioteca. Es más normal para los usuarios de una biblioteca crear su propia subclase que hereda de su clase que cambiar la suya directamente.

+0

¿Hay una manera más corta de agregar una función a una clase después de haber sido declarada? Porque no parece más simple/más limpio que simplemente definirlo dentro de él (no es que yo sepa que debería ser) –

+0

Sin duda, si quieres que sea limpio y simple, solo debes declararlo dentro de la clase. La capacidad de agregar una función después de que se haya definido una clase es bastante esotérica, y probablemente se usa principalmente en situaciones avanzadas que necesitan crear clases completamente nuevas en tiempo de ejecución por alguna razón. ¿Podría describir mejor qué es lo que está tratando de hacer: por qué su clase tiene tantos métodos grandes que quiere ponerlos en archivos separados? – Weeble

+0

Olvídate de lo de "otro módulo". La razón principal por la que quería tenerlos fuera de la definición de clase real era no tener que aplicar sangría a todos ellos (alrededor de 80). Pensé que era "más limpio". De lo contrario, parece más limpio tener funciones dentro de un módulo que crear una clase con 80 funciones. –

-3

no estoy seguro si se ajusta a su caso, pero puede derivar de MyClass y agregar la función que desee.

0

Doy un rodaje a lo que está buscando, donde una clase Helper proporciona funciones para una clase especializada (MyClass)

class Helper(object): 

    def add(self, a, b): 
     return a + b 

    def mul(self, a, b): 
     return a * b 


class MyClass(Helper): 

    def __init__(self): 
     Helper.__init__(self) 
     print self.add(1, 1) 


if __name__ == '__main__': 
    obj = MyClass() 

Esto imprimirá

>>> 2 
1

Sí definitivamente se puede tener funciones fuera de una clase. Aquí hay un pequeño ejemplo ...

def date_parse(date_string): 
    return date(date_string) 


class MyClass: 
    def myFunc(self): 
     pass 

    def myDateFunc(self, date_string): 
     self.date = date_parse(date_string) 
+0

No, quiero decir ¿puedo definir un método de una clase fuera de la clase? –

3

No estoy seguro si esto es útil, pero esto lo hizo un poco más claro para mí. Aunque no estoy seguro de si esto es siempre una buena práctica que hacerlo de esta manera ... primer vistazo

class MyClass1(object): 
    def __init__(self, bar): 
     self.foo = 'updog' 
     MyClass1.foobar = bar 

class MyClass2(object): 
    def __init__(self, bar): 
     self.foo = 'updog' 
     self.foobar = bar 

def bar(self): 
    return "What's " + self.foo 

Vamos a lo que está sucediendo en MyClass1. foobar en esta clase es similar a un método normal como si estuviera definido dentro de la definición de clase (es decir, es un método vinculado a la instancia de esta clase). Vamos a echar un vistazo a lo que esto se parece a ...

In [2]: x = MyClass1(bar) 

In [3]: x.foobar 
Out[3]: <bound method MyClass1.bar of <__main__.MyClass1 object at 0x104346990>> 

In [4]: x.foobar() 
Out[4]: "What's updog" 

¿Cómo difiere esto de MyClass2? En MyClass2, foobar es simplemente una referencia a la función de barra y NO es un método vinculado. Debido a esto, debemos pasar la instancia para que esta función funcione correctamente. p.ej.

In [5]: y = MyClass2(bar) 

In [6]: y.foobar 
Out[6]: <function __main__.bar> 

In [7]: y.foobar() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-7-6feb04878e5f> in <module>() 
----> 1 y.foobar() 

TypeError: bar() takes exactly 1 argument (0 given) 

In [8]: y.foobar(y) 
Out[8]: "What's updog" 

suerte que hace que sea tan claro como el barro ...

Cuestiones relacionadas