2010-12-06 5 views
6

j'ai le code qui contient les deux lignes suivantes en elle: -remplacer le « nouveau » le module

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

Comment pourrait-il être réécrite sans utiliser le module « nouveau »? Je suis sûr que les nouvelles classes de style fournissent une solution de contournement pour cela, mais je ne sais pas comment.

Répondre

2

Cochez cette case thread (mise à jour: le site d'origine a été supprimé).

+0

dit plus tôt que je ne trouve aucune référence au lien cassé, mais voici: http: // python.6.n6.nabble.com/replacement-for-new-instancemethod-in-Python3-tt1546046.html#none Il ne contient pas beaucoup d'informations cependant, je peux me tromper. – geertjanvdk

+0

Désolé, c'était faux de ma part. Up a voté à nouveau! – geertjanvdk

9

Il y a une discussion qui suggère que dans python 3, cela n'est pas nécessaire. Les mêmes œuvres en Python 2.6

Voir:

>>> 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> 
>>> 

Réitérant la question pour chacun de bénéficier, y compris le mien.

Existe-t-il un remplacement dans Python3 pour new.instancemethod? Autrement dit, étant donné une instance arbitraire (et non sa classe), comment puis-je ajouter une nouvelle fonction définie de manière appropriée en tant que méthode?

donc suivant devrait suffire:

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

Pourquoi la valeur de 'c.f' est-elle passée de' > 'à ' sur le deuxième accès dans le shell interactif? Ce n'est pas pour moi quand je l'essaie. – martineau

1

Cela fera la même chose:

>>> Testcase.testName = testFunc 

Ouais, il est vraiment simple.

Votre ligne

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

est en pratique (mais pas en théorie) un noop. :) Vous pouvez tout aussi bien faire

>>> instanceMethod = testFunc 

En fait, en Python 3 Je suis sûr que ce serait la même aussi bien en théorie, mais le nouveau module est parti, je ne peux pas tester dans entraine toi.

0

Pour confirmer qu'il n'est pas nécessaire d'utiliser new.instancemthod() depuis Python v2.4, voici un exemple pour remplacer une méthode d'instance. Il n'est pas non plus nécessaire d'utiliser des descripteurs (même si cela fonctionne).

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. 

Pratique pour les tests unitaires.

3

Vous pouvez remplacer « new.instancemethod » par « 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>'