如何在python中将函数存储为类变量?

Hod*_*lcs 7 python python-3.x

我正在编写一个框架,我希望我的基类使用不同的函数在子类中重命名.我认为最好的方法是使用类属性,就像在的情况下一样A,但是我TypeError在运行它时会得到它rename_columns().然而,它与实现类似B

import pandas as pd

class A:
    my_func_mask = str.lower
    foo = 'bar'

    def rename_columns(self, data):
        return data.rename(columns=self.my_func_mask)

class B(A):

    def rename_columns(self, data):
        return data.rename(columns=self.__class__.my_func_mask)
Run Code Online (Sandbox Code Playgroud)

所以我尝试了上面的一点,我得到以下内容:

a = A()
a.foo # Works fine, gives back 'bar'
a.__class__.my_func_mask # Works as expected `a.__class__.my_func_mask is str.lower` is true
a.my_func_mask # throws TypeError: descriptor 'lower' for 'str' objects doesn't apply to 'A' object
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么我可以使用常规类型(int,str等)值作为类属性并在实例上访问它们,而我不能为函数执行此操作?在这些情况下,在属性查找期间会发生什么?属性解析过程有什么区别?实际上,这两个foomy_func_mask__class__.__dict__让我有点纳闷.谢谢你的澄清!

Mar*_*ers 9

您正在类上存储未绑定的内置方法,这意味着它是一个描述符对象.当你再尝试访问上self,结合描述,但适用的__get__方法调用来完成绑定告诉你,它不能被绑定到你的自定义类的实例,因为该方法只上工作str的情况.这是大多数内置类型方法的严格限制.

你需要以不同的方式存储它; 将它放在另一个容器(如列表或字典)中会避免绑定.或者您可以将其包装在staticmethod描述符中使其绑定并返回原始内容.另一种选择是不将其存储为类属性,只需在其中创建实例属性__init__.

但在这种情况下,我根本不会存储str.lower属性值.我会存储None并回到str.lower你还会遇到的时候None:

return data.rename(columns=self.my_func_mask or str.lower)
Run Code Online (Sandbox Code Playgroud)

设置my_func_maskNone更好地指示将使用默认值,明确区别于明确设置str.lower为掩码.