簡體   English   中英

如何檢查 class 在實例語法中是否具有帶有“attr”的屬性

[英]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__方法

因為你沒有, in運算符切換到后備模式:迭代 object就好像它是一個 sequence ,所以它嘗試object[0] ,然后object[1]等等,直到它遇到IndexError或找到一些東西這等於您要測試的值。 因此,異常,因為item0

使用hasattr而不是getattr ,因為您想要boolean結果。 對於您的__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 關於成員測試操作的參考部分,了解有關如何回退到迭代的詳細信息:

對於未定義__contains__()但定義__iter__()的用戶定義類,如果在迭代y時生成某個值z ,則x in yTrue ,對於該值,表達式x is z or x == z為真. 如果在迭代期間引發異常,就好像in了該異常。

最后,嘗試舊式迭代協議:如果 class 定義了__getitem__() ,當且僅當存在非負 integer 索引i使得x is y[i] or x == y[i]時, x in yTrue x is y[i] or x == y[i] ,並且沒有較低的 integer 索引引發IndexError異常。 (如果引發任何其他異常,就好像引發了該異常)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM