【问题标题】:Python __getattribute__ (or __getattr__) to emulate php __callPython __getattribute__(或 __getattr__)模拟 php __call
【发布时间】:2009-10-26 18:26:40
【问题描述】:

我想创建一个有效地做到这一点的类(将一点 PHP 与 Python 混合)

类中间(对象): # self.apply 是将函数应用于列表的函数 # 例如 self.apply = [] ... self.apply.append(foobar) def __call(self, name, *args) : self.apply(名称,*args)

因此允许代码说:

m = 中间() m.process_foo(a, b, c)

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

【问题讨论】:

    标签: python class


    【解决方案1】:

    您需要在您的对象上定义__getattr__,它是is called if an attribute is not otherwise found

    请注意,对于任何失败的查找都会调用 getattr,并且您不会像函数一样获取它,因此您必须返回将被调用的方法。

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

    【讨论】:

      【解决方案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 返回的东西将被假定不仅仅是一个函数,而是该实例上的绑定方法。所以一定要退货。

      【讨论】:

        【解决方案3】:

        我最近确实这样做了。这是我如何解决它的示例:

        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
        

        【讨论】:

        • 这绝对是可怕的。您可以改用 getattr:result = getattr(self, "FUNC_%d" % func, self.default)(arg)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-04
        • 2011-05-16
        • 1970-01-01
        • 2017-12-12
        • 1970-01-01
        • 1970-01-01
        • 2010-12-03
        相关资源
        最近更新 更多