【发布时间】:2017-01-08 06:43:24
【问题描述】:
我习惯于在编程语言中严格区分标识符(变量名)和字符串。
然而,Python 在两者之间具有一定的延展性。例如在代码中
import networkx as nx
G = nx.Graph()
G.add_edge(1, 2, food='eggs')
for node1, node2, data in G.edges(data=True):
print(data['food'])
我们在第 3 行使用 food 作为标识符,然后在第 5 行检索属性时使用字符串 'food'。
我想更好地了解正在发生的事情。使这种延展性成为可能的编程语言,特别是 Python 中的一般特性是什么?
(请注意,NetworkX 是这个问题的附带问题,这就是为什么我没有在关键字中列出它。)
澄清为什么这个问题不要求解释——并且只是表面上与keyword arguments相关:
有时发生的事情是非常清楚的。比如我们write代码
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
(以我们喜欢的任何顺序使用关键字参数),Python 解释器会看到名称(而不是字符串)bar 和 baz,并且从此期待名称(不是字符串)bar 和 baz , 以任何顺序。
但在其他情况下,这种延展性确实令人费解。例如在 following 代码中解释关键字参数
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
我们在函数调用中引入关键字参数,只是,你瞧,发现它们已经变成了字符串。
从answer 到现在的问题
>>> d = dict(food='eggs')
>>> d['food']
'eggs'
很明显,在 Python 中,d1 和 d2 之间存在零区别:
d1 = {'food':'eggs'}
或
d2 = dict(food='eggs')
d1 发生的事情非常合理。 'food' 的类型是字符串。
但是,d2 又是晦涩难懂的。尽管我们最终得到完全相同的结果,但该语言以某种方式将我们使用的标识符/名称 (food) 塑造成一个字符串。
一般的编程语言,特别是 Python 的特点是什么允许语言将名称塑造成字符串?现在出现了一种模式,是不是 Python 使用了某种机制将名称转换为字符串,但没有将字符串转换为标识符的实例?
【问题讨论】:
-
它实际上不是一个字符串,而是一个键。
-
该问题询问哪种语言功能可以使用
add_edge(food='eggs'),然后使用data['food']中的字符串键检索信息。答案是关键字参数。对add_edge的调用中的food是一个关键字参数,因此该函数在以字符串food作为键的字典中检索它。因此,它可以在实现方面做任何事情,使其在edges()中作为字典可用。这与这个网络库或其他无关,它只是关键字参数,使它成为链接问题的一个很好的副本。 -
所以我们取消了这个问题,这个问题被欺骗了一个关于关键字参数的问题,只是为了三个用户可以提供一个解释关键字参数的答案?
-
“但是,d2 又是晦涩难懂的。” – 不是真的。将关键字参数传递给采用
**kwargs的函数时,所有无关参数都将放入字典kwargs。并且参数名称自动成为所述字典的键。dict(food='eggs')中的food从来都不是标识符(就像变量名一样),它只是参数的名称。参数名称是字符串。
标签: python