经常操作 dict
d = {}
d['name'] ='tom'
d['age'] = 30
这样得代码, 其实我很想有一个 set 方法, 我觉得这样 比上面写法更好
而且 dict 明明有 get 方法, 有 set 很合理
而且还有个 setdefault 方法, 而且这个方法很容易混淆, 因为这个方法 主要作用是获取值, 并不是设置值得, 这个名字一看都不清楚什么意思
总的来说, 我认为应该有 set 方法
但 python 一直没有, 而且既然没有, 后面加上应该不会有任何不兼容
当然这么明显得事情 python 开发组不可能不知道, 那么到底是什么原因 不能放一个 set 方法呢
1
julyclyde 68 天前
set 是 python 语言的关键词
|
2
lucasj 68 天前
我也觉得很合理。
|
3
cmdOptionKana 68 天前
python 语言本身的设计理念就是想一出是一出,很自由,没啥特殊原因,纯粹当时设计者拍脑袋觉得这样够用,后续也没啥大问题就不改了。
|
4
keakon 68 天前
因为有 __setitem__ 方法。提供 dict.get 方法是因为 __getitem__ 在 key 不存在时会抛出异常。
|
5
est 68 天前
.update() 啊
LZ 可以了解一下一个叫 UserDict 的东西。 |
6
009694 68 天前 via iPhone
get 是为了默认值 set 是为了啥? 因为你 java 先入为主的概念
|
7
wxf666 68 天前
|
9
quicknight 68 天前 1
d.set('name', 'tom'),是把 name 给 tom 还是把 tom 给 name ?
d['name'] = 'tom'这种方式没有这个二义性 |
10
Trim21 68 天前
@quicknight 真的会有歧义吗,好奇有哪个 API 设计类似方法的时候把 value 放在前面吗?
|
11
quicknight 68 天前 4
@Trim21 苹果的 OC 和 SWIFT 都是值在前面 KEY 在后面
[dict setObject:@"value" forKey:@"key"] 你如果经常在不同语言中穿梭,或者你只是想看看一个你不懂的语言的逻辑,没有二义性的体验真的好很多 |
13
iorilu OP @wxf666 get , set 相互匹配
我如果用 get 取值, 然后用 set 赋值不是很合理吗 比如 ``` count = p.get('count', 0) p.set('count', count+1) ``` |
15
deplives 68 天前
我也不知道为啥没有显式的 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) |
17
deplives 68 天前
|
18
iorilu OP @Soler 说实话把, 我就是不喜欢方框号操作, 因为我习惯性得觉得方括号就是操作数组类似得东西
主要是我觉得 pyhon 开发组可以加上 set 方法, 至于用不用是开发人员得事, 毕竟还有个 setdefault 呢, 实际上也没啥用, 还不是加上了 |
19
Hookery 68 天前
OP 并没有深刻理解 pythonic
|
21
guyeu 68 天前
set 关键字应该是正解,其次应该是 set 的含义在 dict 这个场景并不能很好地表达这个方法的目的。
dict 是键值对的集合,往集合里添加内容应该是 put 或 insert 。 |
23
llsquaer 68 天前
setdefault 是设置默认值,如果有就不设置了。 你用这个取值?防御性编程啊。
|
24
e3c78a97e0f8 68 天前
[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 。 |
25
sgld 66 天前
d['name'] = 'tom'
这个本身不就是调用的__setitem__ 嘛,所以为啥还需要再建立一个 set()方法再调这个方法呢? 存在这个方法才是真正的多此一举吧。就像 6 楼说的,get 方法是因为需要在不存在时返回默认值。否则直接[]取也是一样的。 |
26
sgld 66 天前
@iorilu Python 对序列取值就是用的[],你可能只是不习惯而已。就像取属性用的是 . 这个也对应了`__getattr__(self, name)`
你这单纯不习惯,不同语言有所不同很正常吧 |
27
woodfizky 66 天前
其实是有类似你说的方法的,但是是 magic method 。
d['key'] = 'value' 等同于 d.__setitem__('key', 'value') 字典主要是还有一个 update 方法,实际上就是遍历 key, value 去做__setitem__ 确实有时候会给人一种设计上不一致的感觉: value = d['key'] 也就是 value = d.__getitem__('key') 上面这种方括号用法有 KeyError 的风险, d['key'] = 'value' 同样是方括号用法,同样是对应一个魔法方法,这个却不会有问题。 然后我换一种风格,用 d.get('key') 和 d.update(other_dict), 都不会出现 KeyError 。 字典 get 方法和__getitem__方法的逻辑并不一样,前者是默认取不到值取默认值,且默认值为 None ;后者取不到值直接报错,且不提供默认值参数。 不过仔细看看就知道了,get 方法是属于字典这种 python 中的 Mapping 类的,并不是直接对应__getitem__这种魔法方法的。通用类是并没有自带 get 和 set 这种方法的。 |