admin管理员组文章数量:1332345
I have a parent class that I made along with a number of child classes that inherit from the parent class. These classes are essentially just python models to read certain documents in from a json or MongoDB and change them from a dictionary into a class. Because of that, I have a standard from_file
class method that is only implemented in the parent class. I would like to get the type hinting worked out so that other modules that use these classes know which class will get returned based on the class that called the method.
Parent
class:
class ParentDoc(ABC):
def __init__(self, ver: int = 1) -> None:
self.ver = ver
def to_dict(self) -> dict:
data = self.__dict__.copy()
data["_class"] = self.__class__.__name__
return data
@classmethod
def from_dict(cls, data: dict) -> ParentDoc:
return cls(ver=data.get("ver", 1))
def to_file(self, file_path: str | Path) -> None:
with open(file_path, "w", encoding="utf8") as json_file:
json.dump(self.to_dict(), json_file)
@classmethod
def from_file(cls, file_path: str | Path) -> ?????:
with open(file_path, "w", encoding="utf8") as json_file:
data = create_from_dict(json.load(json_file))
return data
That helper function in the from_file
method is included below.
def create_from_dict(data: dict):
class_name = data.get("_class")
if class_name == "ParentDoc":
return ParentDoc.from_dict(data)
elif class_name == "ChildDoc":
return ChildDoc.from_dict(data)
elif class_name == "Child2Doc":
return Child2Doc.from_dict(data)
else:
raise ValueError(f"Unsupported class: {class_name}")
Then all of the child classes overload the to_dict
and from_dict
methods but not the to_file
and from_file
methods.
class ChildDoc(DbDoc):
def __init__(self, name: str, ver: int = 1) -> None:
super().__init__(ver=ver)
self.name = name
def to_dict(self) -> dict:
data = super().to_dict()
data.update({"name": self.name})
return data
@classmethod
def from_dict(cls, data: dict) -> ChildDoc:
return cls(name=data["name"])
What should I put where all of the question marks are in the parent class so I can call ChildDoc.from_file(json_path)
and the type hinting will understand that will return a ChildDoc
object and not a ParentDoc
object? I currently don't have any type hinting for the output so the linter thinks that it could be any of the parent or child classes, even though I am calling it using one specific child class. And I suppose I could have better type hinting on the create_from_dict
function as well.
I would like to use the standard type hinting in Python 3.12 (not have to import the typing
module). I have tried Self
but that didn't work.
I have a parent class that I made along with a number of child classes that inherit from the parent class. These classes are essentially just python models to read certain documents in from a json or MongoDB and change them from a dictionary into a class. Because of that, I have a standard from_file
class method that is only implemented in the parent class. I would like to get the type hinting worked out so that other modules that use these classes know which class will get returned based on the class that called the method.
Parent
class:
class ParentDoc(ABC):
def __init__(self, ver: int = 1) -> None:
self.ver = ver
def to_dict(self) -> dict:
data = self.__dict__.copy()
data["_class"] = self.__class__.__name__
return data
@classmethod
def from_dict(cls, data: dict) -> ParentDoc:
return cls(ver=data.get("ver", 1))
def to_file(self, file_path: str | Path) -> None:
with open(file_path, "w", encoding="utf8") as json_file:
json.dump(self.to_dict(), json_file)
@classmethod
def from_file(cls, file_path: str | Path) -> ?????:
with open(file_path, "w", encoding="utf8") as json_file:
data = create_from_dict(json.load(json_file))
return data
That helper function in the from_file
method is included below.
def create_from_dict(data: dict):
class_name = data.get("_class")
if class_name == "ParentDoc":
return ParentDoc.from_dict(data)
elif class_name == "ChildDoc":
return ChildDoc.from_dict(data)
elif class_name == "Child2Doc":
return Child2Doc.from_dict(data)
else:
raise ValueError(f"Unsupported class: {class_name}")
Then all of the child classes overload the to_dict
and from_dict
methods but not the to_file
and from_file
methods.
class ChildDoc(DbDoc):
def __init__(self, name: str, ver: int = 1) -> None:
super().__init__(ver=ver)
self.name = name
def to_dict(self) -> dict:
data = super().to_dict()
data.update({"name": self.name})
return data
@classmethod
def from_dict(cls, data: dict) -> ChildDoc:
return cls(name=data["name"])
What should I put where all of the question marks are in the parent class so I can call ChildDoc.from_file(json_path)
and the type hinting will understand that will return a ChildDoc
object and not a ParentDoc
object? I currently don't have any type hinting for the output so the linter thinks that it could be any of the parent or child classes, even though I am calling it using one specific child class. And I suppose I could have better type hinting on the create_from_dict
function as well.
I would like to use the standard type hinting in Python 3.12 (not have to import the typing
module). I have tried Self
but that didn't work.
1 Answer
Reset to default 3Use typing.Self
to indicate that the class method returns an instance of cls
.
from typing import Self
class P:
@classmethod
def from_file(cls) -> Self:
return cls()
class C1(P):
pass
class C2(P):
pass
reveal_type(P.from_file()) # P
reveal_type(C1.from_file()) # C1
reveal_type(C2.from_file()) # C2
本文标签:
版权声明:本文标题:inheritance - Type hinting in Python 3.12 for inherited classes that use the parent class method without typing module - Stack O 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742327506a2454019.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
typing
module).": PEP 695 is about adding syntactic sugar forGeneric
s et al. It does not deprecatetyping
. – InSync Commented Nov 20, 2024 at 22:46