3

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

class dynamicObject(object):
    pass

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

def someMethod(self):
    pass

这样我就可以做到这一点:

someObject = dyncamicObject()
someObject._someMethod = someMethod
someObject._someMethod()

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

someObject._someMethod(someObject)

这似乎有点奇怪,因为当方法“附加”到对象时不是自我暗示的吗?

我是 Python 思维方式的新手,我试图摆脱与 C# 等语言相同的思维过程,所以这里的想法是能够通过选择我想要添加的验证方法来创建一个用于验证的对象而不是制作某种对象层次结构。我认为 Python 的“自我”想法会对我有利,因为我认为对象会隐含地知道将自己发送到附加到它的方法中。

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

4

5 回答 5

7

尽管在下面我试图回答字面问题,但我认为 Muhammad Alkarouri 的回答更好地解决了应该如何实际解决问题。


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

class dynamicObject(object):
    pass

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

someObject=dynamicObject()
dynamicObject.someMethod=someMethod
someObject.someMethod()
# Hi there!

当你说someObject.someMethod=someMethod, thensomeObject.__dict__得到 key-value pair ('someMethod',someMethod)

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


还有一种替代方法:

import types
someObject.someMethod=types.MethodType(someMethod,someObject,type(someObject))

但这确实令人讨厌,因为您将其定义'someMethod'为 key in someObject.__dict__,这不是方法的正确位置。事实上,你根本没有得到一个类方法,只是一个柯里化函数。这不仅仅是一个技术问题。dynamicObject 的子类将无法继承该someMethod函数。

于 2010-09-22T16:37:29.430 回答
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()
于 2010-09-22T16:57:09.707 回答
0

为什么不使用 setattr?我发现这种方式更加明确。

class dynamicObject(object):
    pass

def method():
    print "Hi"

someObject = dynamicObject()
setattr(someObject,"method", method)
someObject.method()
于 2010-09-22T16:56:46.280 回答
0

有时候方法很简单,需要写一个正则函数,然后再添加,这很烦人。在这种情况下,lambdas 可以来拯救:

    class Square:
        pass

    Square.getX = lambda self: self.x
    Square.getY = lambda self: self.y
    Square.calculateArea = lambda self: self.getX() * self.getY()

希望这可以帮助。

于 2010-09-22T17:40:27.593 回答
0

如果您只想包装另一个类,而不必为任何实例分配新方法,则可以将相关方法设为该类的静态方法:

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!
于 2017-01-26T16:00:20.820 回答