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
iorilu
V2EX  ›  Python

其实我经常好奇一件事, 为什么 Python 得 dict 没有 set 方法, 有人知道什么历史原因吗

  •  
  •   iorilu · 1 天前 · 2070 次点击

    经常操作 dict

    d = {}
    d['name'] ='tom'
    d['age'] = 30
    

    这样得代码, 其实我很想有一个 set 方法, 我觉得这样 比上面写法更好

    而且 dict 明明有 get 方法, 有 set 很合理

    而且还有个 setdefault 方法, 而且这个方法很容易混淆, 因为这个方法 主要作用是获取值, 并不是设置值得, 这个名字一看都不清楚什么意思

    总的来说, 我认为应该有 set 方法

    但 python 一直没有, 而且既然没有, 后面加上应该不会有任何不兼容

    当然这么明显得事情 python 开发组不可能不知道, 那么到底是什么原因 不能放一个 set 方法呢

    24 条回复    2024-10-15 16:30:57 +08:00
    julyclyde
        1
    julyclyde  
       1 天前
    set 是 python 语言的关键词
    lucasj
        2
    lucasj  
       1 天前
    我也觉得很合理。
    cmdOptionKana
        3
    cmdOptionKana  
       1 天前
    python 语言本身的设计理念就是想一出是一出,很自由,没啥特殊原因,纯粹当时设计者拍脑袋觉得这样够用,后续也没啥大问题就不改了。
    keakon
        4
    keakon  
       1 天前
    因为有 __setitem__ 方法。提供 dict.get 方法是因为 __getitem__ 在 key 不存在时会抛出异常。
    est
        5
    est  
       1 天前
    .update() 啊

    LZ 可以了解一下一个叫 UserDict 的东西。
    009694
        6
    009694  
       1 天前 via iPhone
    get 是为了默认值 set 是为了啥? 因为你 java 先入为主的概念
    wxf666
        7
    wxf666  
       1 天前
    不懂就问,`d.set('name', 'tom')` 比 `d['name'] = 'tom'` 好在哪儿呢?

    xing7673
        8
    xing7673  
       1 天前
    @wxf666 = 号作为分隔符更清晰
    quicknight
        9
    quicknight  
       1 天前   ❤️ 1
    d.set('name', 'tom'),是把 name 给 tom 还是把 tom 给 name ?
    d['name'] = 'tom'这种方式没有这个二义性
    Trim21
        10
    Trim21  
       1 天前
    @quicknight 真的会有歧义吗,好奇有哪个 API 设计类似方法的时候把 value 放在前面吗?
    quicknight
        11
    quicknight  
       1 天前   ❤️ 4
    @Trim21 苹果的 OC 和 SWIFT 都是值在前面 KEY 在后面
    [dict setObject:@"value" forKey:@"key"]

    你如果经常在不同语言中穿梭,或者你只是想看看一个你不懂的语言的逻辑,没有二义性的体验真的好很多
    DOLLOR
        12
    DOLLOR  
       1 天前
    @julyclyde 不是吧? python 里 set 可以作为变量名、函数名用
    iorilu
        13
    iorilu  
    OP
       23 小时 38 分钟前
    @wxf666 get , set 相互匹配

    我如果用 get 取值, 然后用 set 赋值不是很合理吗

    比如
    ```
    count = p.get('count', 0)
    p.set('count', count+1)
    ```
    Soler
        14
    Soler  
       22 小时 41 分钟前
    @iorilu 这个世界本来就是不对等的。

    可以使用 p['count'] += 1
    deplives
        15
    deplives  
       22 小时 10 分钟前
    我也不知道为啥没有显式的 set ,但是你可以自己实现一个

    ```python
    import ctypes


    class PyType(ctypes.Structure):
    pass


    class PyObject(ctypes.Structure):
    Py_ssize_t = (
    ctypes.c_int64 if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_int32
    )
    _fields_ = [
    ("ob_refcnt", Py_ssize_t),
    ("ob_type", ctypes.POINTER(PyType)),
    ]


    class PyTypeObject(PyObject):
    _fields_ = [
    ("dict", ctypes.POINTER(PyObject))
    ]


    def inject(class_, method, force=False):
    def _(function):
    name_, dict_ = class_.__name__, class_.__dict__
    proxy_dict = PyTypeObject.from_address(id(dict_))
    namespace = {}
    ctypes.pythonapi.PyDict_SetItem(
    ctypes.py_object(namespace),
    ctypes.py_object(name_),
    proxy_dict.dict
    )
    if not force and namespace.get(name_, {}).get(method, None):
    raise RuntimeError(f"已存在方法 {class_.__name__}.{method}()")
    namespace[name_][method] = function

    return _


    @inject(dict, 'set')
    def dict_set(d, key, value):
    d.update({key: value})
    ```


    a = {}
    a.set("name", "hello")
    print(a)
    Geon97
        16
    Geon97  
       22 小时 10 分钟前
    @wxf666 好在没有 d['name'] = 'tom'可读性强
    iorilu
        18
    iorilu  
    OP
       20 小时 49 分钟前
    @Soler 说实话把, 我就是不喜欢方框号操作, 因为我习惯性得觉得方括号就是操作数组类似得东西

    主要是我觉得 pyhon 开发组可以加上 set 方法, 至于用不用是开发人员得事, 毕竟还有个 setdefault 呢, 实际上也没啥用, 还不是加上了
    Hookery
        19
    Hookery  
       20 小时 49 分钟前
    OP 并没有深刻理解 pythonic
    iorilu
        20
    iorilu  
    OP
       20 小时 47 分钟前
    @deplives 好的, 比较底层得方法, 有空学习下
    guyeu
        21
    guyeu  
       20 小时 24 分钟前
    set 关键字应该是正解,其次应该是 set 的含义在 dict 这个场景并不能很好地表达这个方法的目的。

    dict 是键值对的集合,往集合里添加内容应该是 put 或 insert 。
    julyclyde
        22
    julyclyde  
       20 小时 20 分钟前
    @DOLLOR 嗯我错了。不是保留关键词
    是 built-in type
    你如果用 set 做变量名,相当于覆盖了内置的 set 数据类型吧?
    llsquaer
        23
    llsquaer  
       17 小时 1 分钟前
    setdefault 是设置默认值,如果有就不设置了。 你用这个取值?防御性编程啊。
    e3c78a97e0f8
        24
    e3c78a97e0f8  
       15 小时 51 分钟前
    [Zen of Python:]( https://peps.python.org/pep-0020/)

    There should be one-- and preferably only one --obvious way to do it.

    虽然 Python 开发者自己也经常搞出同一件事的几种做法,但是他们每次都能找到一堆理由。你这个做法完全是 style preference ,并不符合 Zen Of Python 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2612 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:22 · PVG 08:22 · LAX 17:22 · JFK 20:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.