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被注釋掉了!

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

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
添加回答
舉報