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

如何链式调用不返回自身的Python原地修改方法?

实现原地方法的链式调用(无需自定义类)

问题背景

Python 中,set() 的 .add() 这类原地方法不会返回修改后的对象,导致无法链式调用:

S = set()
S = S.add('item1').add('item2').add('item3')

执行后会报错:

AttributeError: 'NoneType' object has no attribute 'add'

偏好链式调用 .add() 是因为它更贴近自然语言,可读性极强,适合偶尔编程的开发者,方便日后读懂自己的代码。已知可通过自定义类(比如 chainOfSets)实现,但想知道不用自定义类的话,有没有更优的实现方式?


方案1:通用链式包装器(最贴近需求)

写一个通用的包装函数,无需为每种对象类型单独定义类,原地修改原对象的同时支持链式调用:

def chain(obj):
    class ChainWrapper:
        def __init__(self, target):
            self.target = target
        
        def __getattr__(self, name):
            attr = getattr(self.target, name)
            if callable(attr):
                def wrapped(*args, **kwargs):
                    result = attr(*args, **kwargs)
                    # 原地方法返回None时,返回包装器自身以支持链式调用;否则返回原结果
                    return self if result is None else result
                return wrapped
            else:
                return attr
        
        def get(self):
            return self.target
    return ChainWrapper(obj)

使用方式:

S = set()
S = chain(S).add('item1').add('item2').add('item3').get()
print(S)  # 输出: {'item1', 'item3', 'item2'}

这个包装器是通用的,不仅支持 set,还能用于 list、dict 等其他带原地方法的对象:

lst = chain([]).append(1).append(2).reverse().get()
print(lst)  # 输出: [2, 1]

方案2:函数式管道写法

如果不想用包装器,可将每个原地操作封装成返回原对象的函数,通过嵌套调用或管道运算符串联:

def set_add(s, item):
    s.add(item)
    return s

def set_remove(s, item):
    s.remove(item)
    return s

使用方式:

# 嵌套调用
S = set()
S = set_add(set_add(set_add(S, 'item1'), 'item2'), 'item3')

# Python 3.10+ 可用管道运算符简化
S = set() | (lambda s: set_add(s, 'item1')) | (lambda s: set_add(s, 'item2')) | (lambda s: set_add(s, 'item3'))
print(S)

方案3:批量操作的简洁写法(适合简单场景)

如果只是批量执行 add 这类单一操作,可通过列表推导式一次性完成,虽不算严格链式调用,但代码简洁:

S = set()
_ = [S.add(item) for item in ['item1', 'item2', 'item3']]
print(S)

注:_ 是占位变量,仅用于触发列表推导式的执行逻辑。


方案对比

  • 通用包装器:最贴近你想要的「点语法链式调用」,通用性强,可读性高,无需重复定义类。
  • 函数式管道:无额外类结构,纯函数风格,适合偏好函数式编程的场景。
  • 列表推导式:仅适合批量单一操作的简单场景,代码最短但可读性稍弱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:25:27