python类nam中的有效字符

2024-05-02 18:18:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在动态地创建python类,我知道并不是所有的字符在这个上下文中都有效。

类库中是否有一个方法可以用来清理随机文本字符串,以便将其用作类名?无论是这个还是一个允许的字符列表都是一个很好的帮助。


关于与标识符名称冲突的添加:如下面的答案中指出的@Ignacio,任何valid as an identifier字符都是类名中的有效字符。您甚至可以使用reserved word作为类名,而不会有任何麻烦。但有个陷阱。如果使用保留字,则无法像其他(非动态创建的)类那样(例如,通过执行globals()[my_class.__name__] = my_class)来访问该类。在这种情况下,保留字将始终优先。


Tags: 方法字符串答案文本名称列表my动态
3条回答

根据Python Language Reference, §2.3, "Identifiers and keywords",有效的Python标识符定义为:

(letter|"_") (letter | digit | "_")*

或者,在regex中:

[a-zA-Z_][a-zA-Z0-9_]*

Python Language Reference, §2.3, "Identifiers and keywords"

Identifiers (also referred to as names) are described by the following lexical definitions:

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

Identifiers are unlimited in length. Case is significant.

有趣的是,标识符的第一个字符是特殊的。在第一个字符之后,数字“0”到“9”对于标识符是有效的,但它们不能是第一个字符。

这里有一个函数,它将返回一个给定任意字符串的有效标识符。其工作原理如下:

首先,我们使用itr = iter(seq)获取输入的显式迭代器。然后是第一个循环,它使用迭代器itr查看字符,直到找到标识符的有效第一个字符。然后它跳出那个循环,运行第二个循环,使用第二个循环的相同迭代器(我们将其命名为itr)。迭代器itr为我们保留了位置;当第二个循环运行时,从迭代器中取出的第一个循环的字符仍会消失。

def gen_valid_identifier(seq):
    # get an iterator
    itr = iter(seq)
    # pull characters until we get a legal one for first in identifer
    for ch in itr:
        if ch == '_' or ch.isalpha():
            yield ch
            break
    # pull remaining characters and yield legal ones for identifier
    for ch in itr:
        if ch == '_' or ch.isalpha() or ch.isdigit():
            yield ch

def sanitize_identifier(name):
    return ''.join(gen_valid_identifier(name))

这是一个干净的和Python的方式来处理一个序列两种不同的方式。对于这样一个简单的问题,我们可以使用一个布尔变量来指示我们是否看到了第一个字符:

def gen_valid_identifier(seq):
    saw_first_char = False
    for ch in seq:
        if not saw_first_char and (ch == '_' or ch.isalpha()):
            saw_first_char = True 
            yield ch
        elif saw_first_char and (ch == '_' or ch.isalpha() or ch.isdigit()):
            yield ch

我不像第一个版本那么喜欢这个版本。对一个字符的特殊处理现在被卷入整个控制流中,这将比第一个版本慢,因为它必须不断检查saw_first_char的值。但在大多数语言中,这是您必须处理控制流的方式!Python的显式迭代器是一个很好的特性,我认为它使这段代码更好。

显式迭代器上的循环与让Python隐式为您获取迭代器一样快,显式迭代器允许我们拆分处理标识符不同部分的不同规则的循环。所以显式迭代器给了我们更干净的代码,运行速度也更快。双赢。

相关问题 更多 >