Python: 从对象中获取具有整数名称的属性
Python: Get attribute with integer name from object
我最近发现我可以在 Python 中做到这一点:
>>> obj = type("SomeObj", (), {1: "a", 2: "b", 3: "c"})()
>>> obj
<__main__.SomeObj object at 0x123456789>
对象obj
肯定有属性1
、2
和3
,如dir()
所示:
>>> dir(obj)
[1, 2, 3, '__class__', '__delattr__', '__dict__', ...]
但是,我无法检索三个属性之一的值。
>>> obj.1
File "<stdin>", line 1
obj.1
^
SyntaxError: invalid syntax
>>> getattr(obj, "1")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'ObjectifiedDict' object has no attribute '1'
>>> obj.__getattribute__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int'
有什么办法吗?
我知道使用整数作为属性名称通常是一个 糟糕的 想法,这让我很好奇。
您正在将字典传递给可以使用整数作为键的类型,没有签入类型来查看您是否传递了有效的 name,因此您会得到一个 SyntaxError 稍后尝试访问该属性:
Identifiers (also referred to as names) are described by the following >lexical definitions:
identifier ::= (letter|"") (letter | digit | "")*
属性必须作为字符串传递给 hasattr 和 getattr,在尝试查找之前引发异常。
PyDoc_STRVAR(hasattr_doc,
"hasattr(object, name) -> bool\n\
\n\
Return whether the object has an attribute with the given name.\n\
(This is done by calling getattr(object, name) and catching exceptions.)");
PyDoc_STRVAR(getattr_doc,
"getattr(object, name[, default]) -> value\n\
\n\
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
When a default argument is given, it is returned when the attribute doesn't\n\
exist; without it, an exception is raised in that case.");
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"hasattr(): attribute name must be string");
return NULL;
}
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
return NULL;
}
整数作为属性名称通常不是一个好主意 应该是不可能 出于上述原因。
您还可以在 python 3 中使用 dir
获得 TypeError: unorderable types: int() < str()
作为属性排序:
PyDoc_STRVAR(dir_doc,
"dir([object]) -> list of strings\n"
"\n"
"If called without an argument, return the names in the current scope.\n"
"Else, return an alphabetized list of names comprising (some of) the attributes\n"
"of the given object, and of attributes reachable from it.\n"
"If the object supplies a method named __dir__, it will be used; otherwise\n"
"the default dir() logic is used and returns:\n"
" for a module object: the module's attributes.\n"
" for a class object: its attributes, and recursively the attributes\n"
" of its bases.\n"
" for any other object: its attributes, its class's attributes, and\n"
" recursively the attributes of its class's base classes.");
您可以访问 1
或 2
或 3
参数
obj = type("SomeObj", (), {1: "a", 2: "b", 3: "c"})()
obj.__class__.__dict__[1]
obj.__class__.__dict__[2]
obj.__class__.__dict__[3]
但不确定它为什么有效.....如果有人可以编辑我的post,解释一下
这适用于 python 3.4.1 和 Python 2.7.6
编辑感谢 Veedrac
vars(type(obj))[1]
vars(type(obj))[2]
vars(type(obj))[3]
编辑 2 只读
但是这些属性是只读的
vars(type(obj))[1]="change" # or obj.__class__.__dict__[1]="change"
Traceback (most recent call last):
File "", line 1, in
TypeError: 'dictproxy' object does not support item assignment
setattr(type(obj), 1, "change")
Traceback (most recent call last):
File "", line 1, in
TypeError: attribute name must be string, not 'int'
我最近发现我可以在 Python 中做到这一点:
>>> obj = type("SomeObj", (), {1: "a", 2: "b", 3: "c"})()
>>> obj
<__main__.SomeObj object at 0x123456789>
对象obj
肯定有属性1
、2
和3
,如dir()
所示:
>>> dir(obj)
[1, 2, 3, '__class__', '__delattr__', '__dict__', ...]
但是,我无法检索三个属性之一的值。
>>> obj.1
File "<stdin>", line 1
obj.1
^
SyntaxError: invalid syntax
>>> getattr(obj, "1")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'ObjectifiedDict' object has no attribute '1'
>>> obj.__getattribute__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int'
有什么办法吗? 我知道使用整数作为属性名称通常是一个 糟糕的 想法,这让我很好奇。
您正在将字典传递给可以使用整数作为键的类型,没有签入类型来查看您是否传递了有效的 name,因此您会得到一个 SyntaxError 稍后尝试访问该属性:
Identifiers (also referred to as names) are described by the following >lexical definitions: identifier ::= (letter|"") (letter | digit | "")*
属性必须作为字符串传递给 hasattr 和 getattr,在尝试查找之前引发异常。
PyDoc_STRVAR(hasattr_doc,
"hasattr(object, name) -> bool\n\
\n\
Return whether the object has an attribute with the given name.\n\
(This is done by calling getattr(object, name) and catching exceptions.)");
PyDoc_STRVAR(getattr_doc,
"getattr(object, name[, default]) -> value\n\
\n\
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
When a default argument is given, it is returned when the attribute doesn't\n\
exist; without it, an exception is raised in that case.");
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"hasattr(): attribute name must be string");
return NULL;
}
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
return NULL;
}
整数作为属性名称通常不是一个好主意 应该是不可能 出于上述原因。
您还可以在 python 3 中使用 dir
获得 TypeError: unorderable types: int() < str()
作为属性排序:
PyDoc_STRVAR(dir_doc,
"dir([object]) -> list of strings\n"
"\n"
"If called without an argument, return the names in the current scope.\n"
"Else, return an alphabetized list of names comprising (some of) the attributes\n"
"of the given object, and of attributes reachable from it.\n"
"If the object supplies a method named __dir__, it will be used; otherwise\n"
"the default dir() logic is used and returns:\n"
" for a module object: the module's attributes.\n"
" for a class object: its attributes, and recursively the attributes\n"
" of its bases.\n"
" for any other object: its attributes, its class's attributes, and\n"
" recursively the attributes of its class's base classes.");
您可以访问 1
或 2
或 3
参数
obj = type("SomeObj", (), {1: "a", 2: "b", 3: "c"})()
obj.__class__.__dict__[1]
obj.__class__.__dict__[2]
obj.__class__.__dict__[3]
但不确定它为什么有效.....如果有人可以编辑我的post,解释一下 这适用于 python 3.4.1 和 Python 2.7.6
编辑感谢 Veedrac
vars(type(obj))[1]
vars(type(obj))[2]
vars(type(obj))[3]
编辑 2 只读
但是这些属性是只读的
vars(type(obj))[1]="change" # or obj.__class__.__dict__[1]="change"
Traceback (most recent call last):
File "", line 1, in
TypeError: 'dictproxy' object does not support item assignment
setattr(type(obj), 1, "change")
Traceback (most recent call last):
File "", line 1, in
TypeError: attribute name must be string, not 'int'