簡體   English   中英

Python 判斷子類是否有基類的方法實現

[英]Determine if subclass has a base class's method implemented in Python

我有一個擴展基數 class 的 class。實例化后,我想檢查子類是否具有從其基類實現的類之一,但我不確定最佳方法。 hasattr(self, '[method]')如果孩子沒有實現,則從 super 返回方法,所以我試圖區分它們。

這是一個例子:

class Base :
   def __init__ ( self,) :
       pass
   
   def fail (self,) :
       pass

# Now create the subclass w/o .fail
class Task ( Base ) :
    def __init__ ( self, ):
         print( hasattr( self, 'fail' ) ) # < returns True

Task()被實例化時,它打印True因為TaskBase繼承.fail 但在這種情況下,我想知道Task沒有實現.fail ,所以我想以某種方式返回False 好像我在尋找類似isimplemented( self, 'fail' )的東西。 我錯過了什么?

IIUC,你可以檢查super().fail == self.fail

class Base:
    def __init__(self):
        pass
   
    def fail(self):
        pass

class Task(Base):
    def __init__(self):
        print(super().fail == self.fail)
    
class Task2(Base):
    def __init__(self):
        print(super().fail == self.fail)
    
    def fail(self):
        # Override
        pass

Output:

t1 = Task()
# True

t2 = Task2()
# False

我不確定我是否理解正確,但聽起來您可能正在尋找抽象基類。 此處為文檔,此處為教程。)如果您在繼承自abc.ABC的基類 class 中指定abstractmethod方法,則嘗試實例化子類將失敗,除非該子類覆蓋了抽象方法。

from abc import ABC, abstractmethod

class Base(ABC):
    @abstractmethod
    def fail(self):
        pass

class Task(Base):
   pass
    
class Task2(Base):
    def fail(self):
        pass

# this raises an exception
# `fail` method has not been overridden in the subclass.
t1 = Task()

# this succeeds
# `fail` method has been overridden in the subclass.
t2 = Task2()

如果您希望檢查發生在class 定義時間而不是實例實例化時間,另一種選擇是在您的基類 class 中編寫一個__init_subclass__方法,每次您對基類 class 進行子類化或從基類 class 繼承基類 class 時都會調用該方法.(你不必在__init_subclass__中引發異常——你可以只向 class 添加一個fail_overriden boolean 屬性,或者做任何你喜歡的事情。)

class Base:
    def fail(self):
        pass

    def __init_subclass__(cls, **kwargs):
        if cls.fail == Base.fail:
            raise TypeError(
               'Subclasses of `Base` must override the `fail` method'
            )
        super().__init_subclass__(**kwargs)


# this class definition raises an exception
# because `fail` has not been overridden
class Task(Base):
    pass


# this class definition works fine.
class Task2(Base):
    def fail(self):
        pass

如果你只是想讓每個實例告訴你fail是否在他們的子類中被覆蓋,你可以這樣做:

class Base:
    def __init__(self):
        print(type(self).fail != Base.fail)

    def fail(self):
        pass

class Task(Base):
   def __init__(self):
       super().__init__()
    
class Task2(Base):
    def __init__(self):
       super().__init__()

    def fail(self):
        pass

t1 = Task() # prints "True"
t2 = Task2() # prints "False"

不確定我是否理解正確但你可以檢查fail方法是否在類的vars中,但沒有繼承到主要的 class。

所以你可以嘗試:

class Base:
    def __init__(self):
        print(self.__dir__())
   
    def fail(self):
        pass

class Task(Base):
    def __init__(self):
        print('fail' not in vars(Task))
    
class Task2(Base):
    def __init__(self):
        print('fail' not in vars(Task2))
    
    def fail(self):
        # Override
        pass
    
t1 = Task()
t2 = Task2()

Output:

True
False

或者使用__dict__

...
class Task(Base):
    def __init__(self):
        print('fail' not in Task.__dict__)
    
class Task2(Base):
    def __init__(self):
        print('fail' not in Task2.__dict__)
    
    def fail(self):
        # Override
        pass
...

暫無
暫無

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

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