Python 如何检测可以';不能通过obj.name语法访问?

Python 如何检测可以';不能通过obj.name语法访问?,python,python-3.x,Python,Python 3.x,setattr将设置不能与常规属性访问一起使用的名称,即obj.name >>> from types import SimpleNamespace >>> my_instance = SimpleNamespace() >>> setattr(my_instance, 'from', 0) # works >>> getattr(my_instance, 'from') 0 >>> my_instanc

setattr
将设置不能与常规属性访问一起使用的名称,即
obj.name

>>> from types import SimpleNamespace
>>> my_instance = SimpleNamespace()
>>> setattr(my_instance, 'from', 0)  # works
>>> getattr(my_instance, 'from')
0
>>> my_instance.from
SyntaxError: invalid syntax
如何检查这些名称以避免使用它们?

在Python 3上

import keyword

type(key) is str and key.isidentifier() and not keyword.iskeyword(key)
我们检查属性名是否是字符串,是否符合Python标识符的格式,是否不是关键字<代码>isidentifier不排除关键字,因此需要进行额外检查


(是的,
isinstance
是一个东西,但我并不真的想允许
str
子类。)

属性名实际上并不非法。这只是因为
from
是一个关键词。你不能这样做;它们作为标识符无效,但作为字符串无效。也许最好的办法是对照a检查,并首先停止设置它们。但也许你的方法不是一个好的开始?不要直接弄乱
\uuu dict\uuuu
,使用
setattr
getattr
来解决这个棘手的问题。顺便说一句,你似乎真的只是想要
类型。SimpleNamespace
如果无效的属性名称“偷偷”进来,那么,它们首先不应该是属性名——它们是数据,应该是dict中的键或值。我认为这是一个XY问题。我不明白你为什么会在这里被否决。我正要给自己发一个链接;这正是它的目的。我的意思是,是的,一般来说,你应该尽量避免使用无效字符串作为关键字/属性名,但是如果你没有充分控制你的输入,这种白名单(必须是合法标识符
str
)和黑名单(但不是
关键字
)的混合是一个不错的选择。我想我的支持票会抵消它。是的,那是我。代码有误报,即它标识的字符串不一定是无效的属性名,而此答案无法解决有关这一点的详细信息。这里是关于这个问题的。@wim:如果您的目标是允许像
这样的属性名来自
,那么它们只是误报。如果您的目标是只允许使用点符号的名称,如问题中所述,那么它们不是误报。你也可以很容易地争辩说像
0
这样的对象是误报的,任何哈希表都应该被接受,因为任何哈希表都可以用作
\uuuuuuuu dict\uuuu
键。@wim:啊,好的。我通常不喜欢允许不能通过
obj.name
语法使用的属性,因为使用它们非常痛苦(必须使用
getattr
/
setattr
operator.attrgetter
,这两者都慢得多,也更难看);我唯一一次考虑它是当我需要使用sigils或类似工具与JSON进行互操作时,但有时这是一个有效的用例。也就是说,我认为你的论点更有意义,因为它是对OP(试图排除有效名称)的回应,而不是对这个答案的回应(这是OP要求的)。@wim:我要指出的是
namedtuple
的例子,它是一个
isidentifier
iskeyword
检查你给它的字段名。排除这些名称是完全有效的设计选择。