Python中的无类方法对任何东西都有用吗?

Ste*_*ett 9 python methods class

我刚刚注意到你可以用Python做到这一点:

def f(self):
    print self.name

class A:
    z=f
    name="A"

class B:
    z=f
    name = "B"
Run Code Online (Sandbox Code Playgroud)

...

print a.z()

>>> A
Run Code Online (Sandbox Code Playgroud)

换句话说,f()行为类似于未在任何类上定义的方法,但可以附加到一个类.当然,如果它需要附加到的对象上的方法或字段(不存在),它将产生运行时错误.

我的问题:这有用吗?它有用吗?有没有解决问题的情况?也许这是定义界面的一种方式?

Dun*_*can 6

是的,它是有用的,它确实有用,但它也很少必须这样做.如果您认为需要在定义类之后对其进行修补,则应始终停止并考虑它是否真的是最好的方法.

一种情况是猴子修补.我已经在一个庞大的Plone系统中完成了这项工作,其中一些方法需要进行小的调整,但是没有任何简单的方法可以正常覆盖行为.在您拥有复杂库的情况下,它提供了一种简单的方法来注入新的或修改过的行为,而无需更改原始库.

想到的另一种情况是,您需要许多可以自动生成的方法.例如数据驱动测试.

def createTest(testcase, somedata, index):
    def test(self):
         "Do something with somedata and assert a result"
    test_name = "test_%d" % index
    setattr(testcase, test_name, test)

for index, somedata in enumerate(somebigtable):
    createTest(MyTestCase, somedata, index)
Run Code Online (Sandbox Code Playgroud)

当MyTestCase是unittest.TestCase时,你可以有一个测试来完成所有数据,但它会在第一次失败时停止,你不得不试图弄清楚哪一行数据失败了.通过动态创建方法,所有测试都单独运行,测试名称告诉您哪一个失败了(上面代码的原始实际构建了一个更有意义的名称,涉及一些数据以及索引).

你不能在类的主体内部做到这一点,因为在定义完成之前无法引用类本身或其字典.但是,您可以使用元类进行类似的操作,因为它允许您在创建类本身之前修改类dict,有时这是一种更简洁的方式来执行相同类型的操作.

另一件需要注意的是,有些情况下这是行不通的.__xxx__在创建类之后,某些特殊方法无法被覆盖:原始定义被保存在内部以外的某个位置,__dict__因此您之后所做的任何更改都可能会被忽略.此外,如果使用元类,有时额外的函数将无法获得元类赋予属性的任何处理作为类定义的一部分.