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

如何在Python函数声明过程中为函数对象添加自定义属性

补充说明:按照Python命名规范,双下划线开头的属性会触发解释器的名称改写(Name Mangling),所以使用单下划线开头的_notes作为自定义属性名确实更合理,以下所有方案都统一使用_notes命名。

实现方案

Python函数体内部的代码只有在函数被调用时才会执行,如果你希望定义函数时就自动生成_notes属性,优先选择装饰器方案;如果可以接受第一次调用函数时生成属性,可以选择内部自引用方案。

方案1:带参数的装饰器(最推荐)

这个方案不需要改动函数内部逻辑,定义时直接传入notes配置,符合Python惯用写法,也不会影响函数本身的执行逻辑。

def add_notes(notes: dict):
    def decorator(func):
        func._notes = notes
        return func
    return decorator

# 定义函数时直接加装饰器配置notes
@add_notes({'Dependencies': ['x', 'y']})
def foo(x:int, y:int)->int:
    '''This is a doc string'''
    return x**2 + y**2

# 直接就能读取属性
print(foo._notes)
# 输出:{'Dependencies': ['x', 'y']}

如果希望把notes写在函数体内部和业务逻辑放在一起,也可以用装饰器自动解析函数源码提取配置:

import inspect
import ast

def extract_notes(func):
    # 解析函数体的抽象语法树,提取内部定义的_notes变量
    tree = ast.parse(inspect.getsource(func))
    for node in ast.walk(tree):
        if isinstance(node, ast.Assign):
            for target in node.targets:
                if isinstance(target, ast.Name) and target.id == '_notes':
                    func._notes = ast.literal_eval(node.value)
                    return func
    func._notes = {}
    return func

@extract_notes
def foo(x:int, y:int)->int:
    '''This is a doc string'''
    _notes = {'Dependencies': ['x', 'y']}
    return x**2 + y**2

print(foo._notes)
# 输出:{'Dependencies': ['x', 'y']}

方案2:函数内部自引用设置(适合动态生成notes场景)

如果你的notes需要根据函数运行时的参数或者状态动态调整,可以在函数内部拿到自身的引用然后设置属性,第一次调用之后就会生成_notes属性:

import inspect

def get_current_func():
    # 通用方法获取当前正在执行的函数对象
    frame = inspect.currentframe().f_back
    func_name = frame.f_code.co_name
    return frame.f_globals[func_name]

def foo(x:int, y:int)->int:
    '''This is a doc string'''
    current_func = get_current_func()
    # 仅第一次调用时初始化notes,避免重复赋值
    if not hasattr(current_func, '_notes'):
        current_func._notes = {'Dependencies': ['x', 'y']}
    return x**2 + y**2

# 调用前没有_notes属性
print(hasattr(foo, '_notes')) # 输出False
# 调用后生成属性
foo(1,2)
print(foo._notes) # 输出{'Dependencies': ['x', 'y']}

方案3:实现可调用类(适合复杂标注场景)

如果你的标注逻辑非常复杂,除了_notes之外还有很多其他自定义属性和方法,可以直接实现一个带__call__方法的类,实例本身可以像函数一样调用,同时可以直接在类定义里声明_notes属性:

class FuncWithNotes:
    _notes = {'Dependencies': ['x', 'y']}
    def __call__(self, x:int, y:int) -> int:
        '''This is a doc string'''
        return x**2 + y**2

foo = FuncWithNotes()
# 像普通函数一样调用
print(foo(1,2)) # 输出5
# 直接读取_notes属性
print(foo._notes) # 输出{'Dependencies': ['x', 'y']}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:03