当前位置: 首页 > 面试题库 >

使用可以接受不是标识符的kwargs关键字参数的函数安全吗?

程举
2023-03-14
问题内容

在Python中,将 不是 Python标识符的关键字参数赋予函数是否安全?这是一个例子:

>>> '{x-y}'.format(**{'x-y': 3})  # The keyword argument is *not* a valid Python identifier
'3'
>>> '{x-y}'.format(x-y=3)
  File "<ipython-input-12-722afdf7cfa3>", line 1
SyntaxError: keyword can't be an expression

我之所以这样问,是因为使用包含破折号的名称对我来说更方便格式化(因为这些值对应于命令行参数中带破折号的名称)。但是这种行为是否可靠(即在不同的Python版本之间是否可以变化)?

我不确定是否正式支持使用非标识符作为关键字参数:实际上,文档内容如下:

如果语法** expression出现在函数调用中,则expression必须计算为一个映射,该映射的内容被视为其他关键字参数。

…其中“关键字参数”被定义为具有 标识符 名称:

keyword_arguments :: = keyword_item(“,” keyword_item)*

keyword_item :: =标识符“ =”表达式

其中标识符在它们可以使用的字符限制(-例如是禁止的):

标识符:: =(字母|“ ”)(字母|数字|“ ”)*

因此,文档表明,**在函数调用中给定的映射应仅包含有效的标识符作为键,但是CPython
2.7接受更多通用键(对于format()和具有**参数的函数,它们不会将值放入变量中)。这是可靠的功能吗?


问题答案:

首先:**{...}具有非标识符名称的调用约定仅在被调用函数具有**kw接收它们的参数的情况下才有效,因为它也无法定义不是有效标识符的显式关键字参数。

我要说的是,keyword_arguments语法仅适用于 源代码
的解析器,不能被视为对**expression结果内容的功能限制。下面的功能描述没有明确限制字典的键,功能定义文档也没有。

相反,因为语法允许的expression,功能规范规定,应该可以解决的映射 ,其中被视为额外的关键字参数的内容
,很显然(对我)有上的按键没有任何限制 可言
,超越适用于Python词典的普通键(键必须是不可变的)。您可以为所有Python护理传递元组或数字键。功能规格说明内容的处理方式,而不是内容必须符合特定格式。

因此,在我看来,功能规范必须 明确
限制**expression字典中的键以禁止您执行操作,因为语法肯定不会。进行更改将是一个巨大的向后不兼容的更改,并且不可能再添加

请注意,即使规范未提及字典键的任何限制,CPython也会:

>>> def f(*args, **kw): print args, kw
... 
>>> f(**{1: 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() keywords must be strings

这是python解释器在调用代码对象(用户定义的函数)时做出的限制。在引发上述异常的部分之后的源代码中直接说明了原因:

/* Speed hack: do raw pointer compares. As names are
   normally interned this should almost always hit. */

通过将关键字限制为字符串,可以实现速度优化。



 类似资料:
  • 问题 你希望函数的某些参数强制使用关键字参数传递 解决方案 将强制关键字参数放到某个*参数或者单个*后面就能达到这种效果。比如: def recv(maxsize, *, block): 'Receives a message' pass recv(1024, True) # TypeError recv(1024, block=True) # Ok 利用这种技术,我们还能在接受

  • 问题内容: 我有一个字典,我需要将键/值作为关键字参数传递..例如。 这可以正常工作, 但是 如果d_args字典中有一些函数不接受的值,则它显然会消失。.说,如果将示例函数定义为 这是一个问题,因为我无法控制或函数的生成。它们都来自外部模块,并且仅接受dict中的某些关键字参数。 理想情况下,我会做 我可能只是从有效的关键字参数列表中过滤出dict,但我想知道: 是否有一种方法可以以编程方式列出

  • 问题内容: 以python内置函数为例。 但是我如何将xs提高到2的幂? 要得到 我知道列表理解会更容易。 问题答案: 根据文档, 不能 这样做(强调我自己): __ 部分参数 在 最左边的 将被前置到位置参数位置参数 您总是可以“修复”以使用关键字args:

  • 问题内容: 我知道JavaScript函数可以接受“任意”数量的参数。 但是我想知道实际上有多少个“任何”个数是否有限制? 例如,假设我向提出了一百万个论点。那行得通吗?还是口译员会翻身? 我猜测最大值是(a)特定于实现的(b),因为对象是类似数组的。 我在语言规范中没有看到这一点,但是可能没有连接点。 问题答案: 尽管没有具体限制规范中参数的理论最大数目这些限制是完全依赖于实现的,最有可能,也将

  • 问题内容: 我遇到了-在我看来-奇怪的行为: 为什么str.split()不会接受关键字参数,即使这很有意义?我在Python2和Python3中都发现了这种现象。 问题答案: 见这个bug和它的superseder。 是CPython中的本机函数,因此具有此处描述的行为: CPython实现细节: 一个实现可能会提供内置函数,这些函数的位置参数没有名称,即使出于文档目的而对其进行了“命名”,因此

  • 问题内容: 我已经尝试了本文和Cassandra doc中的 所有措施。 我已经尝试运行所有版本的Cassandra,包括tarball和Debian软件包中的最新版本3.7,但是执行时总是出错。 错误: 连接错误:(“无法连接到任何服务器”,{‘127.0.0.1’:TypeError(’ref()不带有关键字参数’,)}) 我将Linux Mint从17.3升级到18之前,运行Cassandr