Python:使用Self并动态向对象添加方法
我的想法是:从一个简单的对象开始:Python:使用Self并动态向对象添加方法,python,self,dynamic-method,Python,Self,Dynamic Method,我的想法是:从一个简单的对象开始: class dynamicObject(object): pass 并且能够动态地向其中添加预写方法: def someMethod(self): pass 这样我就可以做到: someObject = dyncamicObject() someObject._someMethod = someMethod someObject._someMethod() 问题是,它希望我指定_someMethod()的self部分,使其看起来像这样:
class dynamicObject(object):
pass
并且能够动态地向其中添加预写方法:
def someMethod(self):
pass
这样我就可以做到:
someObject = dyncamicObject()
someObject._someMethod = someMethod
someObject._someMethod()
问题是,它希望我指定_someMethod()的self部分,使其看起来像这样:
someObject._someMethod(someObject)
这似乎有点奇怪,因为当一个方法“附加”到一个对象时,它不是自我暗示的吗
我不熟悉Python的思维方式,我正试图摆脱像C#这样的语言的思维过程,因此这里的想法是,通过选择我想要添加的验证方法,而不是建立某种对象层次结构,来创建一个用于验证的对象。我认为Python的“自我”思想会对我有利,因为我认为对象会隐式地知道如何将自己发送到附加到它的方法中
需要注意的一点是,该方法没有以任何方式附加到对象(完全不同的文件),所以这可能就是问题所在?也许通过定义方法本身,self实际上就是问题中的方法,因此不能被暗示为对象?尽管下面我已经尝试回答了字面上的问题,我认为 更好地解决问题实际应该如何解决
将方法添加到类
dynamicObject
,而不是对象someObject
:
class dynamicObject(object):
pass
def someMethod(self):
print('Hi there!')
someObject=dynamicObject()
dynamicObject.someMethod=someMethod
someObject.someMethod()
# Hi there!
当你说someObject.someMethod=someMethod
时,然后someObject.\uuu dict\uuuu
获取键值对('someMethod',someMethod)
当你说dynamicObject.someMethod=someMethod
时,someMethod
被添加到dynamicObject
的\uuuuuuuuuuuuuuuuuuuuuuuu dict
。您需要在类中为
someObject.someMethod
作为方法调用。有关这方面的更多信息,请参阅Raymond Hettinger的——毕竟,方法只不过是一个描述符而已还有沙拉布·查图维迪的
还有另一种方法:
import types
someObject.someMethod=types.MethodType(someMethod,someObject,type(someObject))
但这确实是一个令人憎恶的问题,因为您将
'someMethod'
定义为someObject.\uu dict\uuuu
中的键,而这不是方法的正确位置。事实上,您根本没有得到一个类方法,只有一个curry函数。这不仅仅是技术问题。dynamicObject的子类将无法继承someMethod
函数。为什么不使用setattr?我发现这种方式更加明确
class dynamicObject(object):
pass
def method():
print "Hi"
someObject = dynamicObject()
setattr(someObject,"method", method)
someObject.method()
要实现您想要的目标(通过拾取并选择要添加的验证方法来创建验证对象),更好的方法是:
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()
有时,当方法非常简单时,需要编写一个常规函数并在之后添加它,这是很烦人的。在这种情况下,lambdas可以出手相救:
class Square:
pass
Square.getX = lambda self: self.x
Square.getY = lambda self: self.y
Square.calculateArea = lambda self: self.getX() * self.getY()
希望这能有所帮助。如果您只想包装另一个类,而不必为任何实例分配新方法,您可以将该方法设置为该类的staticmethod:
class wrapperClass(object):
@staticmethod
def foo():
print("yay!")
obj = wrapperClass()
obj.foo() // Yay!
然后,您可以为任何其他类提供具有多重继承的.foo
方法
class fooDict(dict, wrapperClass):
"""Normal dict with foo method"""
foo_dict = fooDict()
foo_dict.setdefault('A', 10)
print(foo_dict) // {'A': 10}
foo_dict.foo() // Yay!
现在的问题是,如果dynamicObject在字典中仅为该用途保留该方法,或者它仅为该实例保留该方法(比如在一个方法中),如果您有dynamicObject类的多个实例,那么这些实例中的每一个都将神奇地获得
someMethod
方法。但是当其中一个实例,someInst
,调用someInst.someMethod()
,self
将等于someInst
(正如你所预料的那样)。我不同意“这真的是一个令人憎恶的东西”——这是这个问题的正确答案。我不同意“这真的是一个令人憎恶的东西”-这是这个问题的正确答案。@unutbu:非常感谢!因为他希望将对象引用self
传递给方法。