通过输入继承Python 3中的泛型类型

问题描述 投票:0回答:2

我正在用 Python 3.6 和 mypy 进行一些输入实验。我想设计一个实体类,可以通过两种方式实例化:

  • 使用普通的初始化器 (
    p = Person(name='Hannes', age=27)
    )
  • 从状态对象静态 (
    p = Person.from_state(person_state)
    )。

Entity
派生自
Person
类,将状态类作为通用参数。但是,当使用 mypy 验证代码时,我收到一个错误,指出
Person.from_state
没有从它继承的类中获取状态类型:

untitled2.py:47: 错误:“Entity”的“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)
python generics python-typing mypy
2个回答
2
投票

这是 mypy 中的一个错误,在 mypy 0.700 中已被“修复”。正如评论中的一些人指出的那样,该行代码在新版本中验证得很好。 请注意,在较新版本的 mypy 中,问题中的代码存在不同的问题:

main.py:8: error: Incompatible types in assignment (expression has type "None", variable has type "EntityId") main.py:9: error: Incompatible types in assignment (expression has type "None", variable has type "StateType")

但这超出了问题的范围,由您决定如何解决。


-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)

	
© www.soinside.com 2019 - 2024. All rights reserved.