Python:使用Self并动态地向对象添加方法

Pro*_*ool 3 python self dynamic-method

这是我的想法:从一个简单的对象开始:

class dynamicObject(object):
    pass
Run Code Online (Sandbox Code Playgroud)

并且能够动态添加预先编写的方法:

def someMethod(self):
    pass
Run Code Online (Sandbox Code Playgroud)

所以我可以这样做:

someObject = dyncamicObject()
someObject._someMethod = someMethod
someObject._someMethod()
Run Code Online (Sandbox Code Playgroud)

问题是,它要我指定_someMethod()的self部分,使它看起来像这样:

someObject._someMethod(someObject)
Run Code Online (Sandbox Code Playgroud)

这似乎有点奇怪,因为当一个方法"附加"到一个对象时,它不是自我隐含的吗?

我是Python的新思维方式的新手,我正试图摆脱像C#这样的语言的相同思维过程,因此我想通过选择和选择我想要添加的验证方法来创建一个验证对象而不是制作某种对象层次结构.我认为Python的"自我"想法对我有利,因为我认为该对象会隐含地知道将自己发送到附加到它的方法中.

有一点需要注意,该方法没有以任何方式附加到对象(完全不同的文件),所以可能这是问题?也许通过自己定义方法,self实际上是有问题的方法,因此不能暗示为对象?

unu*_*tbu 6

虽然下面我试图回答文字问题,但我认为 穆罕默德·阿尔卡鲁里的答案更好地解决了问题应该如何解决的问题.


将方法添加到类dynamicObject,而不是对象,someObject:

class dynamicObject(object):
    pass

def someMethod(self):
    print('Hi there!')

someObject=dynamicObject()
dynamicObject.someMethod=someMethod
someObject.someMethod()
# Hi there!
Run Code Online (Sandbox Code Playgroud)

当你说someObject.someMethod=someMethod,然后someObject.__dict__获得键值对('someMethod',someMethod).

当你说dynamicObject.someMethod=someMethod,然后someMethod被添加到dynamicObject's __dict__.您需要someMethod在类中定义 someObject.someMethod以充当方法调用.有关这方面的更多信息,请参阅Raymond Hettinger 关于描述符文章 - 毕竟,方法只不过是一个描述符!- 和Shalabh Chaturvedi 关于属性查找文章.


还有另一种方法:

import types
someObject.someMethod=types.MethodType(someMethod,someObject,type(someObject))
Run Code Online (Sandbox Code Playgroud)

但这确实是一种令人厌恶的事情,因为你将其定义'someMethod'为关键词someObject.__dict__,而不是方法的正确位置.事实上,你根本没有获得类方法,只是一个curried函数.这不仅仅是技术性问题.dynamicObject的子类将无法继承该someMethod函数.


Muh*_*uri 6

要实现您想要的目标(通过选择和选择我想要添加的验证方法来创建验证对象),更好的方法是:

class DynamicObject(object):
    def __init__(self, verify_method = None):
        self.verifier = verify_method
    def verify(self):
        self.verifier(self)

def verify1(self):
    print "verify1"

def verify2(self):
    print "verify2"

obj1 = DynamicObject()
obj1.verifier = verify1

obj2 = DynamicObject(verify2)
#equivalent to
#obj2 = DynamicObject()
#obj2.verify = verify2

obj1.verify()
obj2.verify()
Run Code Online (Sandbox Code Playgroud)

  • +1:这比动态添加方法要好得多. (3认同)