instancemethod装饰器在哪里?

时间:2011-04-12 08:47:52

标签: python decorator instance-method

在我的代码中,我有一个返回类实例的方法,如下所示:

class MyClass:
  def fun( self, *args ): # the method
    return Props( self, *args )

class Props: # the returned object
  def __init__( self, parent, *args ):
    self.parent = parent
    self.args = args

为了保持井井有条,我正在考虑将Props放在MyClass中。然后我想绕过有趣的事情并直接使该类成为MyClass的实例方法,如下所示:

class MyClass:
  @instancemethod # does not exist!
  class fun:
    def __init__( self, parent, *args ):
      self.parent = parent
      self.args = args

注意注释 - instancemethod装饰器不存在。

有没有办法做到这一点,即将可调用对象转换为实例方法?如果我将@instancemethod更改为@classmethod,那么构造工​​作正常,当然除了父类是类,而不是实例。我很惊讶我找不到任何关于什么似乎是相反的操作。

很想清除它!

编辑:

似乎我的问题不明确。我所拥有的是一个成员函数,有趣,它不返回单个值或元组,而是一个充满数据的对象。此数据基于MyClass对象和函数参数的内容生成。我的初始代码完全符合我的要求。第二个代码是我更喜欢写它的方式。

此外,我注意到我正在寻找的装饰器只是以下内容:

def instancemethod( cls ):
  def f( *args ):
    return cls( *args )
  return f

当然,这与我想要绕过的“有趣”方法相同。另请注意,即使看起来像第一眼看上去那么琐碎的'返回cls'也不尽相同。

使用这个装饰器,我的第二个类定义是有效的并产生所需的结果,即a.fun()返回一个(可能)基于以下数据初始化的对象:

a = MyClass()
p = a.fun(1,2,3)

print a        # <__main__.MyClass instance at 0xb775b84c>
print p.parent # <__main__.MyClass instance at 0xb775b84c>
print p.args   # (1, 2, 3)

这仍然留给我一个问题,如果这里定义的instancemethod不能作为python内置,因为它似乎是classmethod和staticmethod旁边的遗漏。但是,如果没有,我想我可以忍受这种结构。

3 个答案:

答案 0 :(得分:1)

我不确定你要做什么,但我怀疑你想阅读descriptors

基本上,描述符是类的一个属性,它本身就是一个定义__get____set__方法的类。在您的情况下,您可以将代码从Props.__init__移至Props.__set__,将Props设置为类的fun属性,并且所有内容都可以按您的意愿运行。

答案 1 :(得分:1)

我认为你无缘无故地过度复杂化了;也许你已经习惯了其他语言,并希望从那里汲取你的习惯。

IIUC,你打算做类似的事情:

class SomeClass:
    # typical stuff
    def __init__(self, other, arg1, arg2, arg3, arg4):
        self.parent= other
        # blah blah

class SomeOtherClass:
    # initialize in __init__, setup stuff
    def __init__(self, initarg1, initarg2):
        self.initarg1= initarg1
        self.initarg2= initarg2

    def fun(self, arg3, arg4):
        # return an instance of SomeClass based on
        # initargs and arguments
        return SomeClass(self, self.initarg1, self.initarg2, arg3, arg4)

答案 2 :(得分:0)

你不需要一个instancemethod装饰器,这可能会起作用:

class MyClass:
  class fun:
    def __init__( self, parent, *args ):
      self.parent = parent
      self.args = args

m = MyClass()
f = m.fun(None, 1, 2, 3)
print f.args

您也可以将第一个示例更改为

class Props:
    def __init__( self, parent, *args ):
        self.parent = parent
        self.args = args


class MyClass:
    fun = Props

m = MyClass()
f = m.fun(None, 1, 2, 3)
print f.args