我想__new__在子類中覆寫以強制它創建父類的實體,為父類的某些關鍵字引數提供默認值。
它被設計為在創建父類實體時提供一些不錯的糖。
- 這是一個可怕的想法嗎?如果是這樣,這樣做的正確方法是什么?
- 這是一個已知的模式嗎?
- 我最喜歡的型別檢查器將如何應對?
class Person:
def __init__(self, name: str, profession: str):
self.name = name
self.profession = profession
class Teacher(Person):
def __new__(self, name: str):
return Person(name=name, profession="teacher")
rita = Person("Rita", profession="surgeon")
bob = Teacher("Bob") # type checkers think `bob` is a Teacher.
uj5u.com熱心網友回復:
正如
也許 StackOverflow 上的 OO-wizards 可以想出比這更吸引人的方法,但這滿足我的要求,我的型別檢查器很高興它bob確實是一個Person.
uj5u.com熱心網友回復:
這是對@LondonRob 的回答稍作調整的建議:如果可能,請使用 anEnum而不是魔術字串來指定 aPerson的職業。
from enum import Enum, auto
from typing import TypeVar
class Profession(Enum):
TEACHER = auto()
SURGEON = auto()
P = TypeVar('P')
class Person:
def __init__(self, name: str, profession: Profession) -> None:
self.name = name
self.profession = profession
@classmethod
def create_teacher(cls: type[P], name: str) -> P:
return cls(name=name, profession=Profession.TEACHER)
這樣做的好處是你可以更干凈地測驗這個人的職業:
>>> Bob = Person.create_teacher('Bob')
>>> Bob.profession is Profession.TEACHER
True
事實上,您甚至可以通過將其作為類的實體方法Profession而不是類上的Person類方法來概括您的替代建構式:
from __future__ import annotations
from enum import Enum, auto
class Person:
def __init__(self, name: str, profession: Profession) -> None:
self.name = name
self.profession = profession
class Profession(Enum):
TEACHER = auto()
SURGEON = auto()
def create(self, name: str) -> Person:
return Person(name=name, profession=self)
使用中:
>>> Bob = Profession.TEACHER.create(name='Bob')
>>> Suzie = Profession.SURGEON.create(name='Suzie')
順便說一句,如果您的類本質上是結構化資料的包裝器,那么您還可以考慮使用dataclasses(無論您是否走這Enum條路線):
from enum import Enum, auto
from dataclasses import dataclass
from typing import TypeVar
class Profession(Enum):
TEACHER = auto()
SURGEON = auto()
P = TypeVar('P')
@dataclass
class Person:
name: str
profession: Profession
@classmethod
def create_teacher(cls: type[P], name: str) -> P:
return cls(name=name, profession=Profession.TEACHER)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314617.html
上一篇:從物件陣列訪問屬性值c#
下一篇:如何宣告可能是兩個類之一的類成員
