【问题标题】:getattr and unicode attributesgetattr 和 unicode 属性
【发布时间】:2021-03-13 12:52:27
【问题描述】:

由于可以在类、方法、变量的标识符中使用 unicode 字符,因此我越来越多地使用它们。我不知道这是不是一个好主意,但它使代码更具可读性(例如,您现在可以使用import numpy as np; π = np.pi; area = r**2 * π!)

现在我注意到以下行为(在 Python 3.8.5 中):

我可以通过以下方式定义一个类A

>>> class A:
...     def x(self):
...         print('x')
...     def ξ(self):
...         print('ξ')
...     def yₓ(self):
...         print('yₓ')

并且可以访问所有方法:

>>> a = A()
>>> a.x()
x
>>> a.ξ()
ξ
>>> a.yₓ()
yₓ

问题来了,如果我想使用getattr() 来访问它们:

>>> attr = getattr(a, 'x')
>>> attr()
x
>>> attr = getattr(a, 'ξ')
>>> attr()
ξ
>>> attr = getattr(a, 'yₓ')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'yₓ'

'A' object has no attribute 'yₓ'
  1. 为什么getattr(a,'ξ') 有效,而getattr(a, 'yₓ') 无效?

我注意到了

>>> dir(a)
[…, 'x', 'yx', 'ξ']
  1. 为什么'ξ' 被保留,而'yₓ' 却默默地转换为'yx'?哪些是“安全”字符,可以使用哪些,让getattr()成功?

  2. 有没有办法让我可以使用yₓ

顺便说一句,yₓ 可以使用,但y₂ 给出了SyntaxError: invalid character in identifier

  1. 为什么我根本不能使用y₂

我知道,解决方法是不使用任何那些花哨的字符,但其中一些使代码真正更具可读性(至少在我看来!)......

【问题讨论】:

标签: python python-3.x


【解决方案1】:

非 ASCII 标识符在 PEP 3131 中定义。在里面,它说:

将整个 UTF-8 字符串传递给一个函数以将字符串规范化为 NFKC

您可以使用unicodedata.normalize 自行测试:

unicodedata.normalize("NFKC", 'ξ') # 'ξ'
unicodedata.normalize("NFKC", 'yₓ') # 'yx'

NFKC is very complicated, but you should be able to find safe characters with a loop.

【讨论】:

  • 这个答案以及@green-cloak-guy 在问题评论(部分)中提供的链接[stackoverflow.com/questions/65093243/… 解释了发生了什么:Python 在解析脚本时规范化标识符。因此.yₓ 实际上变成了.yx,而 保持getattr() 没有规范化属性字符串,导致这种令人费解的行为。因此:python3 class A: def yₓ(self): return 'yₓ' def yx(self): return 'yyxx' a = A() a.yₓ() 打印 yyxx 而不是 yₓ
  • 我想知道,为什么 Python 会规范化标识符。为什么不直接使用 unicode 字符作为标识符?
猜你喜欢
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多