【问题标题】:Is it possible to def a function with a dotted name in Python?是否可以在 Python 中定义一个带点名称的函数?
【发布时间】:2017-02-13 17:41:06
【问题描述】:

在问题What does the "yield" keyword do? 中,我发现正在使用的Python 语法我没想到会有效。这个问题很老并且有大量的选票,所以我很惊讶至少没有人对这个函数定义发表评论:

def node._get_child_candidates(self, distance, min_dist, max_dist):
    if self._leftchild and distance - max_dist < self._median:
       yield self._leftchild
    if self._rightchild and distance + max_dist >= self._median:
       yield self._rightchild  

我试图评估这种语法:

  • 将属性分配给类或对象
  • 重新定义导入模块的功能

到目前为止失败了

SyntaxError: 无效语法

我查找了问题中给出的link (maybe outdated),并在网上搜索了def 的用法,但我没有找到任何解释这种“点名”模式的内容。我使用的是 Python 3,也许这是 Python 2 的一个特性?

此语法是否有效,如果有效,是什么意思?

【问题讨论】:

  • 如果您查看代码,您也会看到node = candidates.pop(),然后您会看到node._get_child_candidates,这是函数中的拼写错误。他们正在节点实例上调用方法get_child_candidates
  • @PadraicCunningham 好吧,在我提到的情况下是一个错字,但在所有情况下语法都是无效的(我试图找出identifier syntax you mentioned,但发现Pcrule 有点混乱) ?
  • python2 和 python3 的唯一区别是 Python 3.0 引入了 ASCII 范围之外的其他字符 即非 ascii 标识符,pep python.org/dev/peps/pep-3131 详细介绍了它

标签: python function syntax-error


【解决方案1】:

不,语法无效。通过检查文档很容易证明。在 Python 2 中,标识符由以下 rules 构造:

identifier ::=  (letter|"_") (letter | digit | "_")*
letter     ::=  lowercase | uppercase
lowercase  ::=  "a"..."z"
uppercase  ::=  "A"..."Z"
digit      ::=  "0"..."9"

在 Py3 中,规则或多或少是相同的,只是扩展到了 Unicode 字符的范围。

看来作者的意思大概是这样的

class Node:
    ...
    def _get_child_candidates(self, ...):
        ...

【讨论】:

  • 是的,似乎只是类内定义的一种快捷表示法
【解决方案2】:

在我的评论中你不能,python3 的有效标识符在docs

标识符(也称为名称)由以下词法定义描述。

Python 中标识符的语法基于 Unicode 标准附件 UAX-31,详细说明和更改定义如下;另请参阅 PEP 3131 了解更多详情。

在 ASCII 范围内 (U+0001..U+007F),标识符的有效字符与 Python 2.x 中的相同:大写和小写字母 A 到 Z、下划线 _ 以及,除了第一个字符,数字 0 到 9。

Python 3.0 引入了 ASCII 范围之外的其他字符(参见 PEP 3131)。对于这些字符,分类使用包含在 unicodedata 模块中的 Unicode 字符数据库版本。

如果您检查代码,您会发现它是原始问题中的错字:

def node._get_child_candidates(self, distance, min_dist, max_dist):
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild  

这是调用者:

result, candidates = list(), [self]
while candidates:
    node = candidates.pop() # creates an instance
    distance = node._get_dist(obj)
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)
    # the _get_child_candidates node is called 
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result

所以在实例上调用了方法_get_child_candidates。所以实际的代码看起来像这样:

def _get_child_candidates(self, distance, min_dist, max_dist):
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild  

这是调用者:

result, candidates = list(), [self]
while candidates:
    node = candidates.pop() # creates an instance
    distance = node._get_dist(obj)
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)
    # the _get_child_candidates node is called 
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 2020-07-26
    • 2019-10-09
    • 1970-01-01
    • 2015-06-25
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多