簡體   English   中英

檢查 object 屬性是否非空 python

[英]Check if object attributes are non-empty python

我可以像這樣檢查 python 列表或字典是否為空

lis1, dict1 = [], {}
# similar thing can be done for dict1
if lis1:
    # Do stuff
else:
    print "List is empty"

如果我嘗試使用我的 class object 執行此操作,即通過鍵入if my_object:這始終評估為True

>>> class my_class(object):
...   def __init__(self):
...     self.lis1 = []
...     self.dict1 = {}
... 
>>> obj1 = my_class()
>>> obj1
<__main__.my_class object at 0x10c793250>
>>> if obj1:
...   print "yes"
... 
yes

我可以專門編寫一個 function 來檢查我的 object 屬性是否為非空,然后調用if obj1.is_attributes_empty(): ,但我更感興趣的是if評估standard data-types (如listdict )為TrueFalse取決於它們包含或為空的項目。

如果我想用我的 class object 實現這個功能,我需要覆蓋或更改哪些方法?

你需要實現__nonzero__方法(或__bool__的__bool__)

https://docs.python.org/2/reference/datamodel.html#object。 非零

class my_class(object):
    def __init__(self):
        self.lis1 = []
        self.dict1 = {}

    def __nonzero__(self):
        return bool(self.lis1 or self.dict1)

obj = my_class()
if obj:
    print "Available"
else:
    print "Not available"

Python還會檢查__len__方法的真實性,但這似乎對您的示例沒有意義。

如果你有很多屬性需要檢查,你可能會喜歡

return any((self.lis1, self.dict1, ...))

它在Python 2.xTruth值測試文檔中給出 -

用戶定義的類的實例,如果類定義__nonzero__()__len__()方法,則該方法返回整數零或bool值False。

對於Python 3.x -

用戶定義的類的實例,如果類定義__bool__()__len__()方法,則該方法返回整數零或bool值False。

根據你的類的定義,如果定義__len__()方法可能有意義,它返回列表長度和__len__()的總和。然后調用此方法來確定是否將對象解釋為TrueFalse在布爾上下文中。 示例 -

class my_class(object):
    def __init__(self):
        self.lis1 = []
        self.dict1 = {}
    def __len__(self):
        print("In len")
        return len(self.lis1) + len(self.dict1)

演示 -

>>> class my_class(object):
...     def __init__(self):
...         self.lis1 = []
...         self.dict1 = {}
...     def __len__(self):
...         print("In len")
...         return len(self.lis1) + len(self.dict1)
...
>>> obj = my_class()
>>> if obj:
...     print("yes")
...
In len
>>> obj.lis1.append(1)
>>>
>>> if obj:
...     print("yes")
...
In len
yes

如果你的類定義(上的Py2) __nonzero__ ,(上PY 3) __bool__或(無論是) __len__ ,那么這將被用來評估該類的對象的“感實性”(如果只__len__定義,一個實例是truthy時它返回非零,並在返回零時返回虛假)。 因此,例如,要使您的類只是報告Py2或Py3中的屬性是否為非空,您需要添加:

 def __bool__(self):
     return bool(self.lis1 or self.dict1)
 __nonzero__ = __bool__ # To make it work on Py2 too

或者,如果您的類實例具有有意義的長度,則定義:

 def __len__(self):
     return len(self.lis1) + len(self.dict1)  # For example; I doubt the length is meaningful in terms of both

並通過支持len(myobject)的副作用獲得布爾行為。

結合使用any()__bool__(self)的答案,以下代碼將允許您使用列表__bool__(self)檢查所有屬性。

class my_class(object):
    def __init__(self):
        self.list1 = []
        self.dict1 = {}

    def __bool__(self):
        check = any([self.__dict__[attr] for attr in self.__dict__.keys()])

        return check

obj1 = my_class()

if obj1:
    print('yes')

此代碼段將不會按預期打印任何內容。

由於許多答案和重復投票建議,您需要覆蓋__nonzero__方法。 但是,從您的評論中,您還希望避免顯式枚舉屬性。 這可以通過這樣的技巧來完成:

class Example(object):
    def __init__(self):
        self._values = {}
        self.attr1 = []
        self.attr2 = {}

    def __setattr__(self, name, value):
        self.__dict__[name] = value
        if not name.startswith('_'):
            self._values[name] = value  # keep track of the assigned attributes

    def __nonzero__(self):
        return any(self._values.itervalues())

這將處理稍后分配或修改的所有公共屬性:

>>> ex = Example()
>>> bool(ex)
False
>>> ex.attr1.append('data')
>>> bool(ex)
True
>>> ex.attr1.pop()
>>> ex.attr3 = 42
bool(ex)
>>> False

沒有正確處理屬性刪除,因為您需要覆蓋__delattr__

內置vars() function 為檢查 object 是否具有任何非空屬性提供了有用的單行代碼。 將其與__nonzero__結合,您將得到以下結果:

def __nonzero__(self):
    return any(list(vars(self).values()))

在 python 中,如果不聲明它們,您將不知道期望哪些屬性。 數據類中提供了聲明屬性的標准方法

https://docs.python.org/3/library/dataclasses.html

from dataclasses import dataclass

@dataclass
class my_class:
   lis1:list = []
   dict1:dict = {}

   def isEmtpy(self)->bool:
      return len(self.lis1)+len(self.dict1)==0

要實施更通用的解決方案,您可能需要在https://github.com/python/cpython/blob/3.11/Lib/dataclasses.py檢查數據類源代碼,尤其是字段訪問器

暫無
暫無

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

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