You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动将实例属性作为参数传递给存储为实例属性的函数?

问题

我正在构建类A以执行特定统计操作,可通过自定义类方法将函数及其参数设为实例属性。我希望调用该函数时,能自动从实例属性中获取参数,而非手动传入。目前的run_function方法尚未实现此功能,示例代码如下:

import pandas as pd 

df = pd.DataFrame(
    [[1,2.,"a"],[0,8.,"q"],[1,3.5,"a"],[1,9.5,"g"]],
    columns=["binary","float","letters"]
    )

c = "binary"
v = 1

def test_fn(df,c:str,v:list):
    if not isinstance(v,list):
        v = [v]

    return (df[c].isin(v)).sum()


class A():
    def __init__(self,df):
        self.df = df

    def _set_fn_args(self,**kwargs):
        self.__dict__.update(kwargs)

    def set_function(self,function,**kwargs):
        self.fn = function
        self._set_fn_args(**kwargs)

    def run_function(self,df=None,**kwargs):
        if df is None:
            df = self.df
        return self.fn(df,**kwargs)

a = A(df)
a.set_function(test_fn,c=c,v=v)

a.__dict__.keys()
# dict_keys(['df', 'fn', 'c', 'v'])

a.fn
# <function __main__.test_fn(df, c: str, v: list)>

a.run_function(c=a.c,v=a.v) 
# 3 

当前调用run_function需手动传入参数,失去了将参数存储为实例属性的意义。我希望调用run_function()时,能根据参数名称自动从实例a中获取c、v等必要参数。请问是否有简便实现方式,或是否有其他类编写方案可达成此目标?

解决方案

方法1:通过inspect模块自动匹配函数参数

利用inspect.signature获取目标函数的参数列表,自动从实例属性中提取对应参数,同时支持传入参数覆盖实例属性,通用性最强。

import pandas as pd
import inspect

df = pd.DataFrame(
    [[1,2.,"a"],[0,8.,"q"],[1,3.5,"a"],[1,9.5,"g"]],
    columns=["binary","float","letters"]
)

c = "binary"
v = 1

def test_fn(df,c:str,v:list):
    if not isinstance(v,list):
        v = [v]
    return (df[c].isin(v)).sum()

class A():
    def __init__(self,df):
        self.df = df

    def _set_fn_args(self,**kwargs):
        self.__dict__.update(kwargs)

    def set_function(self,function,**kwargs):
        self.fn = function
        self._set_fn_args(**kwargs)

    def run_function(self,df=None,**kwargs):
        if df is None:
            df = self.df
        # 获取函数的参数签名
        sig = inspect.signature(self.fn)
        # 收集参数:优先用传入的kwargs,无则从实例属性取
        fn_args = {}
        for param_name in sig.parameters:
            if param_name == 'df':
                fn_args['df'] = df
            else:
                fn_args[param_name] = kwargs.get(param_name, getattr(self, param_name))
        return self.fn(**fn_args)

a = A(df)
a.set_function(test_fn,c=c,v=v)
print(a.run_function())  # 输出3
# 传入参数覆盖实例属性
print(a.run_function(v=[0]))  # 输出1

方法2:用functools.partial提前绑定参数

在set_function阶段就把实例的df和参数与目标函数绑定,后续run_function直接调用绑定后的函数即可,逻辑更简洁。

import pandas as pd
from functools import partial

df = pd.DataFrame(
    [[1,2.,"a"],[0,8.,"q"],[1,3.5,"a"],[1,9.5,"g"]],
    columns=["binary","float","letters"]
)

c = "binary"
v = 1

def test_fn(df,c:str,v:list):
    if not isinstance(v,list):
        v = [v]
    return (df[c].isin(v)).sum()

class A():
    def __init__(self,df):
        self.df = df
        self.bound_fn = None

    def set_function(self,function,**kwargs):
        # 绑定实例df和传入的参数
        self.bound_fn = partial(function, self.df, **kwargs)

    def run_function(self,**kwargs):
        # 若传入新参数,合并原有绑定参数与新参数
        if kwargs:
            temp_fn = partial(self.bound_fn.func, self.bound_fn.args[0], **{**self.bound_fn.keywords, **kwargs})
            return temp_fn()
        return self.bound_fn()

a = A(df)
a.set_function(test_fn,c=c,v=v)
print(a.run_function())  # 输出3
print(a.run_function(v=[0]))  # 输出1

方法3:直接合并实例属性与传入参数

适合明确参数不会与实例其他属性冲突的场景,直接过滤实例中存储的函数参数,与传入参数合并后调用函数,实现成本最低。

import pandas as pd

df = pd.DataFrame(
    [[1,2.,"a"],[0,8.,"q"],[1,3.5,"a"],[1,9.5,"g"]],
    columns=["binary","float","letters"]
)

c = "binary"
v = 1

def test_fn(df,c:str,v:list):
    if not isinstance(v,list):
        v = [v]
    return (df[c].isin(v)).sum()

class A():
    def __init__(self,df):
        self.df = df

    def _set_fn_args(self,**kwargs):
        self.__dict__.update(kwargs)

    def set_function(self,function,**kwargs):
        self.fn = function
        self._set_fn_args(**kwargs)

    def run_function(self,df=None,**kwargs):
        if df is None:
            df = self.df
        # 过滤实例中存储的函数参数(排除df、fn等核心属性)
        fn_kwargs = {k:v for k,v in self.__dict__.items() if k not in ['df','fn']}
        # 用传入参数覆盖实例参数
        fn_kwargs.update(kwargs)
        return self.fn(df,**fn_kwargs)

a = A(df)
a.set_function(test_fn,c=c,v=v)
print(a.run_function())  # 输出3
print(a.run_function(v=[0]))  # 输出1

内容的提问来源于stack exchange,提问作者stat_is_quo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:15:35