Python __getattribute __(或__getattr__)来模拟php __call

时间:2009-10-26 18:26:40

标签: python class

我想创建一个有效地执行此操作的类(将一些PHP与Python混合)

  class Middle(object) :
    #  self.apply is a function that applies a function to a list
    #  e.g   self.apply = []  ... self.apply.append(foobar)       
    def __call(self, name, *args) :
       self.apply(name, *args)   

因此允许代码说:

   m = Middle()
   m.process_foo(a, b, c)

在这种情况下,__ call()是PHP __call()方法,当在对象上找不到方法时调用该方法。

3 个答案:

答案 0 :(得分:3)

您需要在对象上定义__getattr__is called if an attribute is not otherwise found

请注意,任何失败的查找都会调用getattr,并且你不会像函数all那样得到它,所以你必须返回将被调用的方法。

def __getattr__(self, attr):
  def default_method(*args):
    self.apply(attr, *args)
  return default_method

答案 1 :(得分:2)

考虑将参数作为参数传递给您的方法,而不是编码到方法名称中,然后将其神奇地用作参数。

你在哪里编写的代码不知道它将调用哪些方法?

为什么要调用c.do_Something(x)然后解压方法名称而不是只调用c.do('Something', x)

在任何情况下,处理不合理的属性都很容易:

class Dispatcher(object):
    def __getattr__(self, key):
       try:
           return object.__getattr__(self, key)
       except AttributeError:
           return self.dispatch(key)

    def default(self, *args, **kw):
        print "Assuming default method"
        print args, kw

    def dispatch(self, key):
        print 'Looking for method: %s'%(key,)
        return self.default

测试:

>>> d = Dispatcher()
>>> d.hello()
Looking for method: hello
Assuming default method
() {}

这似乎充满了“陷阱” - getattr 返回的东西将被假定为不仅仅是一个函数,而是该实例上的绑定方法。所以一定要归还。

答案 2 :(得分:-1)

我最近这样做了。这是我如何解决它的一个例子:

class Example:
    def FUNC_1(self, arg):
        return arg - 1

    def FUNC_2(self, arg):
        return arg - 2

    def decode(self, func, arg):
        try:
            exec( "result = self.FUNC_%s(arg)" % (func) )
        except AttributeError:
            # Call your default method here
            result = self.default(arg)

        return result

    def default(self, arg):
        return arg

和输出:

>>> dude = Example()
>>> print dude.decode(1, 0)
-1
>>> print dude.decode(2, 10)
8
>>> print dude.decode(3, 5)
5