Han*_*tri 7 python generics entity types python-3.6
我正在做一些在Python 3.6中输入的实验.我想设计一个可以通过两种方式实例化的实体类:
p = Person(name='Hannes', age=27))p = Person.from_state(person_state)).Person派生的Entity类将状态类作为泛型参数.但是,当使用pypy验证代码时,我收到一个错误,即Person#from_state没有从它继承的类中获取状态类型:
untitled2.py:47:错误:"实体"的"from_state"的参数1具有不兼容的类型"UserState"; 预期的"StateType"
我认为通过继承Entity[UserState],StateType将被绑定UserState并且子类中的方法签名将相应地更新.
这是完整的代码.我已经标记了我怀疑我做错了事的路线?????.第47行几乎位于底部并在代码中标记.
from typing import TypeVar, Generic, NamedTuple, List, NewType
EntityId = NewType('EntityId', str)
StateType = TypeVar('StateType')
class Entity(Generic[StateType]):
id: EntityId = None
state: StateType = None
@classmethod
def from_state(cls, state: StateType): # ?????
ret = object.__new__(cls)
ret.id = None
ret.state = state
return ret
def assign_id(self, id: EntityId) -> None:
self.id = id
class UserState(NamedTuple):
name: str
age: int
class User(Entity[UserState]):
def __init__(self, name, age) -> None:
super().__init__()
self.state = UserState(name=name, age=age)
@property
def name(self) -> str:
return self.state.name
@property
def age(self) -> int:
return self.state.age
def have_birthday(self) -> None:
new_age = self.state.age+1
self.state = self.state._replace(age=new_age)
# Create first object with constructor
u1 = User(name='Anders', age=47)
# Create second object from state
user_state = UserState(name='Hannes', age=27)
u2 = User.from_state(user_state) # Line 47
print(u1.state)
print(u2.state)
Run Code Online (Sandbox Code Playgroud)
Gij*_*ben -3
我知道这个问题有点老了,但仅供将来参考:
from __future__ import annotations
from typing import NamedTuple, Optional, Type
class UserState(NamedTuple):
name: str
age: int
class Entity:
id: Optional[str]
state: UserState
@classmethod
def from_state(cls: Type[Entity], state: UserState) -> Entity:
entity_from_state: Entity = object.__new__(cls)
entity_from_state.id = None
entity_from_state.state = state
return entity_from_state
def assign_id(self, id: str) -> None:
self.id = id
class User(Entity):
def __init__(self, name: str, age: int) -> None:
self.state = UserState(name=name, age=age)
@property
def name(self) -> str:
return self.state.name
@property
def age(self) -> int:
return self.state.age
def have_birthday(self) -> None:
new_age = self.state.age + 1
self.state = self.state._replace(age=new_age)
# Create first object with constructor
u1 = User(name="Anders", age=47)
# Create second object from state
user_state = UserState(name="Hannes", age=27)
u2 = User.from_state(user_state) # Line 47
print(u1.state)
print(u2.state)
Run Code Online (Sandbox Code Playgroud)