如何检查 class 是否具有带有“'attr' in instance”语法的属性
How to check if a class has an attribute with `'attr' in instance` syntax
我希望能够使用 'attr' in instance
语法来检查我的数据类是否具有指定的属性,但我似乎无法使其工作。
我想要的是与此示例相同的行为 pandas
import pandas as pd
df = pd.DataFrame(columns=['a', 'b', 'c'])
print('a' in df)
True
但仅针对自定义数据类
from dataclasses import dataclass
@dataclass
class User:
email: int
password: str
blocked_at: float = None
def __getitem__(self, item):
return getattr(self, item)
user = User('email@test.com', 'password')
print(user['email'])
'email' in user
email@test.com
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [35], in <cell line: 1>()
----> 1 'email' in user in User.__getitem__(self, item)
7 def __getitem__(self, item):
----> 8 return getattr(self, item)
TypeError: getattr(): attribute name must be string
这是因为您没有定义正确的钩子。您要实施 __contains__
method.
因为你没有,in
运算符切换到回退模式:迭代对象 就好像它是一个序列,所以它尝试 object[0]
,然后是 object[1]
,等等,直到遇到 IndexError
或找到与您要测试的值相等的值。因此,例外,因为 item
是 0
.
使用 hasattr
而不是 getattr
,因为您想要 布尔值 结果。对于您的 __getitem__
,您要确保将 AttributeError
异常转换为 KeyError
异常,以保持界面一致:
from __future__ import annotations
from dataclasses import dataclass
@dataclass
class User:
email: int
password: str
blocked_at: float = None
def __getitem__(self, item: str) -> str | int | float | None:
try:
return getattr(self, item)
except AttributeError:
raise KeyError(item) from None
def __contains__(self, item: str) -> bool:
return hasattr(self, item)
演示:
>>> user = User('email@test.com', 'password')
>>> print(user['email'])
email@test.com
>>> 'email' in user
True
>>> user["nonesuch"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 12, in __getitem__
KeyError: 'nonesuch'
有关 in
如何回退到迭代的详细信息,请参阅 Python reference section on membership test operations:
For user-defined classes which do not define __contains__()
but do define __iter__()
, x in y
is True
if some value z
, for which the expression x is z or x == z
is true, is produced while iterating over y
. If an exception is raised during the iteration, it is as if in
raised that exception.
Lastly, the old-style iteration protocol is tried: if a class defines __getitem__()
, x in y
is True
if and only if there is a non-negative integer index i
such that x is y[i] or x == y[i]
, and no lower integer index raises the IndexError
exception. (If any other exception is raised, it is as if in raised that exception).
我希望能够使用 'attr' in instance
语法来检查我的数据类是否具有指定的属性,但我似乎无法使其工作。
我想要的是与此示例相同的行为 pandas
import pandas as pd
df = pd.DataFrame(columns=['a', 'b', 'c'])
print('a' in df)
True
但仅针对自定义数据类
from dataclasses import dataclass
@dataclass
class User:
email: int
password: str
blocked_at: float = None
def __getitem__(self, item):
return getattr(self, item)
user = User('email@test.com', 'password')
print(user['email'])
'email' in user
email@test.com
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [35], in <cell line: 1>()
----> 1 'email' in user in User.__getitem__(self, item)
7 def __getitem__(self, item):
----> 8 return getattr(self, item)
TypeError: getattr(): attribute name must be string
这是因为您没有定义正确的钩子。您要实施 __contains__
method.
因为你没有,in
运算符切换到回退模式:迭代对象 就好像它是一个序列,所以它尝试 object[0]
,然后是 object[1]
,等等,直到遇到 IndexError
或找到与您要测试的值相等的值。因此,例外,因为 item
是 0
.
使用 hasattr
而不是 getattr
,因为您想要 布尔值 结果。对于您的 __getitem__
,您要确保将 AttributeError
异常转换为 KeyError
异常,以保持界面一致:
from __future__ import annotations
from dataclasses import dataclass
@dataclass
class User:
email: int
password: str
blocked_at: float = None
def __getitem__(self, item: str) -> str | int | float | None:
try:
return getattr(self, item)
except AttributeError:
raise KeyError(item) from None
def __contains__(self, item: str) -> bool:
return hasattr(self, item)
演示:
>>> user = User('email@test.com', 'password')
>>> print(user['email'])
email@test.com
>>> 'email' in user
True
>>> user["nonesuch"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 12, in __getitem__
KeyError: 'nonesuch'
有关 in
如何回退到迭代的详细信息,请参阅 Python reference section on membership test operations:
For user-defined classes which do not define
__contains__()
but do define__iter__()
,x in y
isTrue
if some valuez
, for which the expressionx is z or x == z
is true, is produced while iterating overy
. If an exception is raised during the iteration, it is as ifin
raised that exception.Lastly, the old-style iteration protocol is tried: if a class defines
__getitem__()
,x in y
isTrue
if and only if there is a non-negative integer indexi
such thatx is y[i] or x == y[i]
, and no lower integer index raises theIndexError
exception. (If any other exception is raised, it is as if in raised that exception).