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

Python中setattr绑定函数后__name__属性不符问题咨询

问题分析与解决方法

我来帮你理清楚这个问题哈~

为什么f.con.__name__会返回condition?

当你用setattr(self, accessor, self.condition)把condition方法赋值给实例的con/don属性时,本质上只是把同一个函数对象的引用绑定到了不同的实例属性上。函数对象的__name__属性是在它被定义的时候就固定下来的,存储的是它定义时的名称(也就是condition),并不会因为这个函数被赋值给不同的变量或属性就自动改变。

打个比方:就像你给一个叫「张三」的朋友起了个外号「阿三」,但朋友本身的本名还是「张三」,不会因为外号而改变——这里的condition函数就是「张三」,con/don只是它的“外号”,函数自身的__name__自然还是原来的名字。

解决方法

下面给你两种可行的解决思路,你可以根据自己的需求选择:

方法1:用functools.wraps修改函数元数据

functools模块里的wraps装饰器可以帮我们修改函数的元数据(包括__name__),让它“伪装”成我们指定的名称。如果你的condition方法需要用到当前的属性名(比如查询self.accessor_column),还可以结合partial来传递参数:

import functools

class Filter:
    def __init__(self, column=['poi_id', 'tp.event'], access=['con', 'don']):
        self.column = column
        self.access = access
        self.accessor_column = dict(zip(self.access, self.column))
        self.set_conditions()

    def condition(self, accessor_name, name):
        # 这里可以直接用传入的accessor_name查询对应的列
        target_col = self.accessor_column.get(accessor_name)
        print(f"当前使用列: {target_col}")
        return name

    def set_conditions(self):
        for poi_column, accessor in zip(self.column, self.access):
            # 用partial绑定accessor参数,同时修改__name__
            wrapped_func = functools.partial(self.condition, accessor)
            wrapped_func.__name__ = accessor
            setattr(self, accessor, wrapped_func)

方法2:动态创建新的函数对象

如果你想更彻底一点,可以直接创建新的函数对象,复用原函数的代码逻辑,同时指定新的名称:

import types

class Filter:
    def __init__(self, column=['poi_id', 'tp.event'], access=['con', 'don']):
        self.column = column
        self.access = access
        self.accessor_column = dict(zip(self.access, self.column))
        self.set_conditions()

    def condition(self, name):
        return name

    def set_conditions(self):
        for poi_column, accessor in zip(self.column, self.access):
            # 创建新的函数对象,指定新的名称
            new_func = types.FunctionType(
                self.condition.__code__,
                self.condition.__globals__,
                name=accessor,
                argdefs=self.condition.__defaults__,
                closure=self.condition.__closure__
            )
            # 将新函数绑定到当前实例
            bound_func = new_func.__get__(self, Filter)
            setattr(self, accessor, bound_func)

验证效果

运行修改后的代码,就能得到你想要的结果:

>>> f = Filter()
>>> print(f.con('linux'))
linux
>>> print(f.con.__name__)
con
>>> print(f.don.__name__)
don

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:32:43