在Python中调用它时是否可以创建一个不存在的方法?

时间:2014-04-29 04:33:02

标签: python

如果我有这门课程:

class MyClass(object):
   pass

然后我这样做:

instance = MyClass()
instance.new_method()

我遇到了一个AttributeError Exception,但是我想以dinamically方式创建这个方法并返回一个especifc值。有可能吗?

3 个答案:

答案 0 :(得分:2)

首先,Python检查是否存在具有此类名称的属性,如果是,则会调用它。没有明确的方法可以过早地检测是否会调用此属性。

这是实现目标的棘手方法:

class Dispatcher(object):

    def __init__(self, caller, name):
        self.name = name
        self.caller = caller

    def __call__(self, *a, **ka):
        print('Call on Dispatcher registered!', 
              'Will create method on',
              self.caller.__class__.__name__,
              'now.')
        setattr(self.caller, self.name, self.mock)
        return getattr(self.caller, self.name)(*a, **ka)

    @classmethod
    def mock(cls, *a, **ka):
        return 'Some default value for newly created methods.'


class MyClass(object):

    def __getattr__(self, attr):
        return Dispatcher(self, attr)


instance = MyClass()
print(instance.new_method, '\n')
print(instance.new_method(), '\n')
print(instance.new_method(), '\n')
print(instance.other_method)

输出:

<__main__.Dispatcher object at 0x0000000002C07DD8> 

Call on Dispatcher registered! Will create method on MyClass now.
Some default value for newly created methods. 

Some default value for newly created methods. 

<__main__.Dispatcher object at 0x0000000002C07DD8>

虽然此解决方案非常全面,但每次尝试访问不存在的属性时,它都会返回Dispatcher的新实例。

如果调用Dispatcher实例(例如Dispatcher(self, attr)()),它会将mock设置为对象的名为attr的新方法,作为第一个参数传递给构造

答案 1 :(得分:1)

是的,你可以这样做:

class MyClass(object):
   pass

def some_method():
    pass

name = 'new_method'    

setattr(MyClass, name, classmethod(some_method))

答案 2 :(得分:1)

有可能。

>>> class MyClass(object):
        pass

>>> instance = MyClass()
>>> def new_method(cls, x):
        print x


>>> MyClass.new_method = new_method
>>> instance.new_method(45)
45

请注意,new_methodcls作为第一个参数(实例)在作为实例方法调用时被隐式传递。