亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在不忘記在子類中添加屬性裝飾器的情況下覆蓋抽象屬性方法?

如何在不忘記在子類中添加屬性裝飾器的情況下覆蓋抽象屬性方法?

當年話下 2023-06-20 10:36:15
如果我重寫了一個抽象屬性方法,但忘記指定它仍然是子類中的屬性方法,我希望 Python 解釋器對我大喊大叫。class Parent(metaclass=ABCMeta):  @property  @abstractmethod  def name(self) -> str:    passclass Child(Parent):  @property # If I forget this, I want Python to yell at me.  def name(self) -> str:    return 'The Name'if __name__ == '__main__':  print(Child().name)Python 真的沒有內置方法可以做到這一點嗎?我真的必須創建自己的裝飾器來處理這種行為嗎?
查看完整描述

3 回答

?
白衣非少年

TA貢獻1155條經驗 獲得超0個贊

您可以使用metaclass:


class Parent(type):

  def __new__(cls, name, bases, body):

    if 'name' not in body.keys() or body['name'].__class__.__name__ != 'property':

      raise TypeError(f"Can't instantiate class {name} without property name")

    return super().__new__(cls, name, bases, body)



class Child(metaclass=Parent):

  @property # If I forget this, raise TypeError

  def name(self) -> str: # also, name must be implemented

    return 'The Name'


if __name__ == '__main__':

  print(Child().name)

這引發了一個TypeError: Can't instantiate class Child without property name- when@property被注釋掉了!


查看完整回答
反對 回復 2023-06-20
?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

您可以在 Parent 的方法中進行運行時檢查,如果是方法__init__則引發異常。name


class Parent(metaclass=ABCMeta):

  def __init__(self):

    assert not callable(self.name)


  @abstractmethod

  def name(self) -> str:

    pass



class GoodChild(Parent):

  @property

  def name(self) -> str:

    return 'The Name'



class BadChild(Parent):

  def name(self) -> str:

    return 'Whoops, not a property'



if __name__ == '__main__':

  good_child = GoodChild()

  print(good_child.name)   # Prints 'The Name'

  bad_child = BadChild()   # Raises an AssertionError when initialized


查看完整回答
反對 回復 2023-06-20
?
qq_笑_17

TA貢獻1818條經驗 獲得超7個贊

TLDR - 在我看來不值得麻煩:


在 linting/mypy 和單元測試之間,應該涵蓋你的大部分需求和圍繞類分析/元類的小技巧可能不值得他們帶來額外的認知負擔。你只會“失敗”你的裝飾一次,但必須閱讀異國情調的腳手架代碼,用于您每次都想做的事情。


詳細信息 - 實際使用被標記為什么?


ie if badchild1.name.startswith("John"): 將在運行時失敗,我希望 mypy 或 pylint 也能標記分析,因為它將成為一個方法對象。串聯也是如此。唯一真正需要監督的候選人是 f 字符串,直接布爾值或==不!=關心它不是字符串的相等比較。


pylint是這樣說的:


test_171_prop.py:11 Method 'name' was expected to be 'property', found it instead as 'method' (invalid-overridden-method)

但是mypy沒有問題。


但是,如果我添加這個:


child = Child()


print("name:" + child.name)

然后mypy說:


test_171_prop.py:16: error: Unsupported operand types for + ("str" and "Callable[[], str]")

Found 1 error in 1 file (checked 1 source file)

并使用 2 條新行運行代碼說:


TypeError: can only concatenate str (not "method") to str


查看完整回答
反對 回復 2023-06-20
  • 3 回答
  • 0 關注
  • 190 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號