开发者

replacing the "new" module

I have code which contains the following two lines in it:-

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

How could it be re-written without using the "new" module? Im sure new style开发者_Python百科 classes provide some kind of workaround for this, but I am not sure how.


There is a discussion that suggests that in python 3, this is not required. The same works in Python 2.6

  • http://mail.python.org/pipermail/python-list/2009-April/531898.html

See:

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

Reiterating the question for every one's benefit, including mine.

Is there a replacement in Python3 for new.instancemethod? That is, given an arbitrary instance (not its class) how can I add a new appropriately defined function as a method to it?

So following should suffice:

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


You can replace "new.instancemethod" by "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>'


This will do the same:

>>> Testcase.testName = testFunc

Yeah, it's really that simple.

Your line

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

Is in practice (although not in theory) a noop. :) You could just as well do

>>> instanceMethod = testFunc

In fact, in Python 3 I'm pretty sure it would be the same in theory as well, but the new module is gone so I can't test it in practice.


To confirm that it's not needed to use new.instancemthod() at all since Python v2.4, here's an example how to replace an instance method. It's also not needed to use descriptors (even though it works).

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.

Handy for unit testing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜