2010-12-06 4 views
6

tengo código que contiene las dos líneas siguientes en él: -la sustitución de la "nueva" módulo

instanceMethod = new.instancemethod(testFunc, None, TestCase) 
setattr(TestCase, testName, instanceMethod) 

Como no podía ser re-escrito sin necesidad de utilizar el "nuevo" módulo? Estoy seguro de que las nuevas clases de estilo proporcionan algún tipo de solución para esto, pero no estoy seguro de cómo.

Respuesta

2

Compruebe esto thread (actualizado: el sitio original fue eliminado).

+0

comentado anteriormente que no he encontrado ninguna referencia al enlace roto, pero aquí está: http: // python.6.n6.nabble.com/replacement-for-new-instancemethod-in-Python3-tt1546046.html#none Aunque no contiene mucha información, podría estar equivocado. – geertjanvdk

+0

Lo siento, eso estuvo mal de mi parte. ¡Votado nuevamente! – geertjanvdk

9

Hay una discusión que sugiere que en Python 3, esto no es necesario. Las mismas obras en Python 2.6

Ver:

>>> class C: pass 
... 
>>> c=C() 
>>> def f(self): pass 
... 
>>> c.f = f.__get__(c, C) 
>>> c.f 
<bound method C.f of <__main__.C instance at 0x10042efc8>> 
>>> c.f 
<unbound method C.f> 
>>> 

Reiterando la pregunta para cada uno de los beneficios, incluida la mía.

¿Hay un reemplazo en Python3 para new.instancemethod? Es decir, dada una instancia arbitraria (no su clase), ¿cómo puedo agregar una nueva función definida apropiadamente como método?

Así pues, siguiendo debería ser suficiente:

TestCase.testFunc = testFunc.__get__(None, TestCase) 
+1

¿Por qué el valor de 'c.f' cambió de' > 'a' 'en el segundo acceso en el shell interactivo? No funciona para mí cuando lo intento. – martineau

1

Esto hará lo mismo:

>>> Testcase.testName = testFunc 

Sí, es así de simple.

Su línea

>>> instanceMethod = new.instancemethod(testFunc, None, TestCase) 

en la práctica (aunque no en teoría) un NOOP. :) Se podía así hacer

>>> instanceMethod = testFunc 

De hecho, en Python 3 Estoy bastante seguro de que sería el mismo en teoría también, pero el nuevo módulo se ha ido así que no puedo probarlo en práctica.

0

Para confirmar que no es necesario utilizar new.instancemthod() en absoluto desde Python v2.4, aquí hay un ejemplo de cómo reemplazar un método de instancia. Tampoco es necesario usar descriptores (incluso si funciona).

class Ham(object): 
    def spam(self): 
     pass 

h = Ham() 
def fake_spam(): 
    h._spam = True 
h.spam = fake_spam 
h.spam() 

# h._spam should be True now. 

Práctico para la prueba unitaria.

3

Puede reemplazar "new.instancemethod" por "types.MethodType":

from types import MethodType as instancemethod 

class Foo: 
    def __init__(self): 
     print 'I am ', id(self) 

def bar(self): 
    print 'hi', id(self) 

foo = Foo() # prints 'I am <instance id>' 
mm = instancemethod(bar, foo) # automatically uses foo.__class__ 
mm()   # prints 'I have been bound to <same instance id>' 

foo.mm  # traceback because no 'field' created in foo to hold ref to mm 
foo.mm = mm # create ref to bound method in foo 
foo.mm()  # prints 'I have been bound to <same instance id>' 
Cuestiones relacionadas