标签: python-typing

Python 中的模板类

我正在尝试用 Python 创建代数,但发现创建参数化类很困难。

作为一个例子,考虑这个ProductWeight类。它包含另外两个Weight对象,具有强制类型(至少静态地,通过mypy)。

这将失败,因为(根据设计)我无法访问类W1W2调用它们的类方法,例如zero. (它们没有指定;ProductWeight没有模板化。)ProductWeight当我创建实例时,不知道要绑定到它的类型。

from typing import Generic, TypeVar
W1 = TypeVar("W1")
W2 = TypeVar("W2")

class ProductWeight(Generic[W1, W2]):
    def __init__(self, value1: W1, value2: W2):
        self.value1_ = value1
        self.value2_ = value2

    @classmethod
    def zero(cls):
        return cls(W1.zero(), W2.zero())  # Will fail - no access to W1 and W2.
    
Run Code Online (Sandbox Code Playgroud)

相比之下,这在 C++ 中很简单:因为类型是参数化的,所以它能够查找W1::Zero.

template<typename W1, typename W2>
public:
    ProductWeight(W1 w1, W2 w2) : value1_(w1), …
Run Code Online (Sandbox Code Playgroud)

python templates metaclass python-3.x python-typing

6
推荐指数
1
解决办法
1万
查看次数

为什么 Final 字典不能用作 TypedDict 中的文字?

我正在尝试完成以下任务(请参阅mypy Playground):

from typing import TypedDict, Final

account_schema: Final = {"name": str, "email": str}

Account = TypedDict("Account", account_schema)
AccountPatch = TypedDict("AccountPatch", account_schema, total=False)
Run Code Online (Sandbox Code Playgroud)

我的想法是,我可以在一个地方指定我的模式,一个版本需要所有字段(Account插入数据库时​​),另一个版本使所有字段可选(AccountPatch更新数据库时)。

来自PEP 586

限定符Final用作声明变量有效的简写Literal

mypy错误如下:

error: TypedDict() expects a dictionary literal as the second argument
Run Code Online (Sandbox Code Playgroud)

为什么不允许TypedDict字典Final作为其第二个参数?

对于我的核心问题,我是否可以对两个TypedDicts 使用相同的架构(一个具有整体性,一个不具有整体性),而不必复制架构?

python dictionary type-hinting mypy python-typing

6
推荐指数
1
解决办法
590
查看次数

更好的设计以避免违反里氏替换原则

我遇到了里氏替换原则的问题,并且不太确定解决它的最佳方法是什么。

有问题的代码

class BaseModel:
    def run(self, base_model_input: BaseModelInput) -> BaseModelOutput:
        """Throws NotImplemented or @abstractmethod"""
        pass

class SpecificModel(BaseModel):
    def run(self, specific_input: SpecificModelInput) -> SpecificModelOutput:
        # do things...
Run Code Online (Sandbox Code Playgroud)

我很清楚为什么这不是一个很好的代码,以及为什么它违反了里氏替换原则。我想知道如何更好地设计我的系统以避免这个问题。

从根本上讲,我有一个BaseModel类似于接口的类,提供一些run扩展类必须实现的方法。但是扩展类还处理特定的输入/输出,它们也是基本输入/输出类的扩展(继承SpecificModelInputBaseModelInput添加一些字段和功能,与输出相同)

这里更好的方法是什么?

python design-patterns liskov-substitution-principle python-3.x python-typing

6
推荐指数
1
解决办法
945
查看次数

如何在 Python 中使用不同数量的参数来注释相互依赖的函数参数和返回类型(&lt; 3.10)?

编辑注释 1:到目前为止,我发现PEP 612解决了这个问题 - 从 Python 3.10 开始 - 通过引入typing.ParamSpec. 所以这个问题专门针对 Python 3.9 或更早版本。

编辑注释 2:原始示例过于狭窄,因为它的返回类型与参数类型完全匹配,但问题实际上是关于更通用的情况,其中函数的参数签名相同,但返回类型相同是不同的。(也欢迎允许不同参数签名的更通用的解决方案。)

问题:我正在使用一个转换函数,它接收一个函数作为参数,并返回另一个函数作为其结果。传递的函数可以有任意数量和类型的参数(为简单起见,我们可以坚持位置参数),返回的函数以与原始函数相同的方式调用(具有相同数量和类型的参数),并有一个返回值type 取决于传递函数的返回类型(但不一定等于它;例如,它可以是包含原始返回类型的值和某个给定类型的另一个值的元组)。

如何以反映传递和返回函数的签名依赖性的方式注释转换函数?

一个简单的例子:

from typing import Callable


def transform(original_function: Callable) -> Callable:
    def new_function(*args):
        extra_payload = <do some calculation>
        return original_function(*args), extra_payload
    return new_function


def f(x: int, s: str) -> bool:
    ...


f(3, 'abc')  # this is a valid call
f('abc', 3)  # PyCharm warns about wrong argument types

# The goal is to have a …
Run Code Online (Sandbox Code Playgroud)

python annotations type-hinting higher-order-functions python-typing

6
推荐指数
1
解决办法
1395
查看次数

导入类只是为了在 python 中输入?

我正在尝试使用 Python 3.8 中的输入,但有点卡住了。示例:我主要在main.py. 我还有一个类util.py,其中包含一些辅助函数和类。但这些类还需要从main.pyTyping 导入类。现在,当我想使用util.pyin中的函数时main.py中的函数时,我还需要导入它 - 但随后我会因为循环导入而收到错误(这是正确的)。

有没有解决的办法?

提前致谢!

python python-import python-typing

6
推荐指数
2
解决办法
2172
查看次数

Python - 类中的静态方法创建该类的实例

我有从 JSON 创建的 Python 数据类(实际上有很多)。我想要一种从 JSON 创建类实例的方法。

我有这样的事情:

class FromJSONMixin:
    @staticmethod
    @abstractmethod
    def from_json(json: Union[Dict, TypedDict], **kwargs):
        raise NotImplementedError


class PatientJSON(TypedDict):
    ID: str
    Name: str
    Description: str
    BirthDate: str


@dataclass
class Patient(FromJSONMixin):
    name: str
    birth_date: str
    description: str

    @staticmethod
    def from_json(json: PatientJSON, **kwargs) -> Patient:
        return Patient(
        name=json["Name"],
        birth_date=json["BirthDate"],
        description=raw_data["Description"])
Run Code Online (Sandbox Code Playgroud)

我想Patient从中创建对象PatientJSON(结构与现有数据库相关,我必须与它集成;它还进行一些名称属性翻译,如上所示)。我创建了FromJSONMixin来显式标记可以从 JSON 的相关类创建的类(例如PatientJSON)。

问题:-> Patient:我收到零件错误Unresolved reference 'Patient'。为什么?我无法在同一类的方法中键入类对象?我是否必须放弃输入返回类型?

python json static-methods dictionary python-typing

6
推荐指数
1
解决办法
2664
查看次数

mypy 错误:赋值中的类型不兼容(表达式的类型为“Dict[&lt;nothing&gt;, &lt;nothing&gt;]”,目标的类型为“List[str]”)

我尝试在现有字典的第二层实例化一个空字典,然后为其分配一个键值对,但 MyPy 抛出错误。

这是一个最小的示例,当激活 MyPy 检查时它将重现它:

result = {"Test": "something"}
result['key'] = {}
result['key']['sub_key'] = ["some string", "another string"]
Run Code Online (Sandbox Code Playgroud)

这里的错误将类似于:

mypy(error): Incompatible types in assignment (expression has type
"Dict[<nothing>, <nothing>]", target has type "List[str]")
Run Code Online (Sandbox Code Playgroud)

我该如何防止这个错误?根据类似的问题,建议这样做

result['key'] = {}  # type: ignore
Run Code Online (Sandbox Code Playgroud)

作为一种解决方法,但这似乎不是很优雅,这就是为什么我想知道是否还有更多的事情可以做。

python type-hinting mypy python-typing

6
推荐指数
1
解决办法
9027
查看次数

Typehint 使用 importlib 动态导入模块

给出如下内容:

import importlib

module_path = "mod"
mod = importlib.import_module(module_path, package=None)
print(mod.Foo.Bar.x)
Run Code Online (Sandbox Code Playgroud)

哪里mod.py

class Foo:
    class Bar:
        x = 1
Run Code Online (Sandbox Code Playgroud)

mypy file.py --strict 引发以下错误

file.py:7: error: Module has no attribute "Foo"  [attr-defined]
Run Code Online (Sandbox Code Playgroud)

我想知道应该如何进行类型提示,或者这是否是通常会被忽略的东西# type: ignore[attr-defined] (假设代码是必要的,并且唯一的选项是类型提示或忽略类型提示)


为什么我importlib在这种情况下使用

使用的方式importlib是有一些路径:

x.y.<changes>.z
Run Code Online (Sandbox Code Playgroud)

哪里<changes>是动态的,其他的都是固定的。我确信该模块将包含正在调用的属性,但由于<changes>,importlib用于导入。

可以概括为:

我不确切地知道我将导入哪个模块,但我知道它将有一个Foo

python type-hinting python-importlib mypy python-typing

6
推荐指数
1
解决办法
1269
查看次数

可选 [Union] 与 Union[None] 的首选 Python 键入语法

据我所知,以下两种类型在 Python 中是等效的:

Optional[Union[A, B]]

Union[A, B, None]

是否有一个明确的约定可供选择,例如 PEP 中的条款?

python type-hinting mypy union-types python-typing

6
推荐指数
0
解决办法
2738
查看次数

Pylance 如何获取动态定义类的类型注释?

from types import ModuleType\nfrom typing import Any, Dict, Tuple, Type, TypeVar\n\nfrom . import default\n\n_T = TypeVar("_T", bound=type)\n\nclass settings_meta(type):\n    def __new__(\n        cls: Type[_T],\n        name: str,\n        bases: Tuple[type, ...],\n        namespace: Dict[str, Any],\n        settings: ModuleType,\n        **kwargs: Any,\n    ) -> _T:\n        from inspect import ismodule\n\n        namespace = {\n            key: val\n            for key, val in vars(settings).items()\n            if not key.startswith("__") and not ismodule(val)\n        }\n        namespace["__annotations__"] = {\n            key: val\n            for key, val in vars(settings)["__annotations__"].items()\n            if key in namespace.keys()\n        }\n        return type.__new__(cls, name, bases, namespace, **kwargs)\n\n    def …
Run Code Online (Sandbox Code Playgroud)

python type-hinting visual-studio-code python-typing pylance

6
推荐指数
0
解决办法
569
查看次数