Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:使用Self并动态向对象添加方法_Python_Self_Dynamic Method - Fatal编程技术网

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
传递给方法。