我已经看到并尝试了How would one decorate an inherited method in the child class?给出的答案,但无济于事。
样本数据:
import pandas as pd
df = pd.DataFrame([('Tom', 'M'), ('Sarah', 'X')], columns=['PersonName', 'PersonSex'])
我正在使用pandera
库来进行DataFrame数据质量和验证。我有一个类BaseClass
,它定义了一些我将在许多模式中使用的函数,例如:
class BaseClass:
def check_valid_sex(col):
return col.isin(['M', 'F'])
我在我的schema类中继承了这个类,我将在其中应用检查。这里,首先,是一个不使用这个类并在SchemaModel
中显式编写检查的示例。
import pandera as pa
from pandera.typing import Series
class PersonClass(pa.SchemaModel):
PersonName: Series[str]
PersonSex: Series[str]
@pa.check('PersonSex')
def check_valid_sex(cls, col):
return col.isin(['M', 'F'])
PersonClass.validate(df)
我想做的是在其他SchemaModel
类中重用check_valid_sex
函数,其中有一个PersonSex
列,类似于:
import pandera as pa
from pandera.typing import Series
class PersonClass(pa.SchemaModel, BaseClass):
PersonName: Series[str]
PersonSex: Series[str]
# apply the pa.check function to the BaseClass function to inherit the logic
validate_sex = classmethod(pa.check(BaseClass.check_valid_sex, 'PersonSex'))
PersonClass.validate(df)
这应该会返回一个有效的验证,但是没有起作用,因为我不相信这个函数被正确注册了。我怎样才能修饰父类而不覆盖它呢?简单地用修饰器参数来修饰。
2条答案
按热度按时间yquaqz181#
这里的decorator实际上是一个decorator构造函数,它会对调用它的对象进行装饰,因此需要遵循相同的模式,用字段名构造
check
,然后使用它手动 Package 基类函数:不太清楚为什么基类(不是
classmethod
)接受cls
,而子类试图 Package 成classmethod
,如果只是子类应该是classmethod
,你可以这样做:来 Package 它,但是如果基类方法实际上是
classmethod
,它会变得更难看;你必须打开它,例如,你要用BaseClass.check_valid_sex.__func__
替换BaseClass.check_valid_sex
(将函数绑定到类,然后只提取未绑定的函数),或者在Python 3.10+中,您可以通过执行BaseClass.__dict__['check_valid_sex'].__wrapped__
来避免创建绑定类方法(它查找原始的classmethod
,绕过描述符协议,并直接提取它 Package 的函数)。您需要这样做,以便获得干净的原始函数,而不是永久地绑定到父类(即使在子类上调用cls
,cls
仍将是BaseClass
)。mwg9r5ms2#
有一个接口可以向pandera的check-engine注册自定义的check-function,它可以实现重用:
图纸