首页 > 解决方案 > 如何在python中将函数存储为类变量?

问题描述

我正在编写一个框架,我希望我的基类使用不同的函数在子类中重命名。我认为最好的方法是使用类属性,例如 in 的情况A,但是当我TypeError像 in 一样运行它时我得到了 s 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)

因此,我对上述内容进行了一些实验,得到以下结果:

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

我的问题是为什么我可以使用常规类型的(int、str 等)值作为类属性并在实例上访问它们,而我不能对函数这样做?在这些情况下,属性查找期间会发生什么?属性解析过程有什么区别?实际上两者foomy_func_mask在,__class__.__dict__所以我有点困惑。感谢您的澄清!

标签: pythonpython-3.x

解决方案


您在类上存储了一个未绑定的内置方法,这意味着它是一个描述符对象。然后,当您尝试访问它时self,描述符绑定适用,但为完成绑定而调用的__get__方法告诉您它不能绑定到您的自定义类实例,因为该方法仅适用于str实例。这是大多数内置类型方法的严格限制。

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

但在这种情况下,我根本不会存储str.lower为属性值。当您仍然遇到时,我会存储None并回退到:str.lowerNone

return data.rename(columns=self.my_func_mask or str.lower)

设置my_func_maskNone更好地指示将使用默认值,与显式设置str.lower为掩码明显不同。


推荐阅读