V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
shinonome
V2EX  ›  Python

Python 函数参数是选 list 还是*arg 呢

  •  
  •   shinonome · 73 天前 · 2690 次点击
    这是一个创建于 73 天前的主题,其中的信息可能已经有所发展或是发生改变。
    def list_arg(*test_list:int):
        for i in test_list:
            print(i)
    
    list_arg(*[1,2])
    
    def list_arg(test_list:list[int]):
        for i in test_list:
            print(i)
    
    list_arg([1,2])
    

    之前一直是用的 list, 因为本来就是就 list,(不是 list 我就[int]包装一下),所以也没多想,今天看 nonebot 的时候看到有这种用法,想问问大家这俩种大家会怎么选呢, 在参数是

    int|list[int]

    的情况下

    def deep_update(
        mapping: dict[K, Any], *updating_mappings: dict[K, Any]
    ) -> dict[K, Any]:
        """深度更新合并字典"""
        updated_mapping = mapping.copy()
        for updating_mapping in updating_mappings:
            for k, v in updating_mapping.items():
                if (
                    k in updated_mapping
                    and isinstance(updated_mapping[k], dict)
                    and isinstance(v, dict)
                ):
                    updated_mapping[k] = deep_update(updated_mapping[k], v)
                else:
                    updated_mapping[k] = v
        return updated_mapping
    
    13 条回复    2024-09-02 08:53:38 +08:00
    iOCZS
        1
    iOCZS  
       73 天前
    不应该是 list_arg(1,2)么?
    shinonome
        2
    shinonome  
    OP
       73 天前
    @iOCZS #1 我的意思是可能是 1,2,3,4,5,6,...或者是 1
    fakepoet
        3
    fakepoet  
       73 天前
    选 1 ,传入一个 mutable 参数大部分时候都是一个坏的做法。
    darcyC
        4
    darcyC  
       73 天前
    可变参数用法在做库的时候用的比较多,个人或团队用的话,很多时候倾向于 list ,而不是 * 或 **(除非你有特别的理由)
    vituralfuture
        5
    vituralfuture  
       73 天前 via Android
    首先是符合语义,其次是如果你有其他参数要传的话,就只能用列表了,不然其他参数只能用关键字传参
    NoOneNoBody
        6
    NoOneNoBody  
       73 天前   ❤️ 1
    应该习惯参数分开不同的意义,前面的例子分开元素没有意义,所以没必要用*
    用*多是
    1. 输入有固定顺序,但不太关注名字,例如 from to ,start end 这些,使用者一般不考虑参数名直接输入两个数,且约定俗成一般不会搞错顺序
    2. 多个参数,但长度不定,但函数内的计算是针对单个元素的,或者只使用其中某个位置的
    如 def select_b(a,b,*args): return b 这样可以传一个*tuple 过去

    你这个想法是“批量”,即使只有一个也可扔一组过去,循环一次而已
    但建议也是要有单个处理的思想,将来 pandas/numpy 这些使用的向量函数,都是单个处理的,向量化能直接把单个处理的函数应用在一组数据,如果一开始就写成批量处理,反而没有向量化了(不能转为向量函数);向量化在海量数据处理中是很重要的,速度比 for 循环要高很多
    但如果不考虑将来在大数据中复用,也可以忽略

    PS: 传递单个参数习惯用 tuple ,因为 tuple 是 hashable ,而 list 是 unhashable ,将来遇到多进程调用某个函数(这个函数最初设计没有考虑到用在多进程),就可能出现不能 pickle 无法继续的情况
    Sawyerhou
        7
    Sawyerhou  
       73 天前 via Android
    轻易不用 list ,一般情况下可变对象不可作为参数。
    CaptainD
        8
    CaptainD  
       73 天前
    @Sawyerhou #7 是不作为参数默认值吧
    Sawyerhou
        9
    Sawyerhou  
       73 天前 via Android
    @CaptainD https://blog.csdn.net/qq_37189082/article/details/95325868
    引用传递改变原始对象,原始对象其他人可能也在用但我并不知道,也可能我在用但其他人不知道,如果一定要传传 copy 或者元组似乎更保险一点。
    ClericPy
        10
    ClericPy  
       73 天前
    具体情况具体分析吧

    稍微大点的协同开发项目,共享几个入参和结果的 typeddict / dataclass
    iorilu
        11
    iorilu  
       72 天前
    这两个不是一回事阿, 有什么疑问

    难道 lz 认为是一样得吗

    test_list:list[int]
    一个是确定是个集合, 空集合也是集合


    *test_list:int
    一个一般至少有一个参数, 可能多个参数
    jack2020
        12
    jack2020  
       72 天前
    倾向使用 *test_list:int ,特别是如果参数 test_list 是希望不可变的场景
    nevermoreluo
        13
    nevermoreluo  
       71 天前
    你自己写的 list_arg 的例子和你说的 deep_update 完全不是一回事情
    1. *updating_mappings 是为了接收多个更新字典 deep_update({"a":1}, {"b":2}, {"c":3}) -> {"a":1,"b":2,"c":3}
    2. 你写的*[1,2]那叫解包,这样写好处很少甚至迷惑人,除非 test_list 不允许被内部更改用 Unpacking 和 packing 再组一个新的 list ,但是这样太隐晦了 甚至不如函数内部再写一个 test_list = test_list.copy()
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1212 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:36 · PVG 02:36 · LAX 10:36 · JFK 13:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.