首页 > 解决方案 > 创建一个类型化的装饰器作为类方法并在另一个文件中导入/使用它

问题描述

我正在尝试将类型添加到我的项目中。我几乎复制了装饰工厂的模式。

这是链接文档中提供的示例:

from typing import Any, Callable, TypeVar

F = TypeVar("F", bound=Callable[..., Any])

def route(url: str) -> Callable[[F], F]:
    ...

@route(url='/')
def index(request: Any) -> str:
    return 'Hello world'

这是我的实际代码:

from json import loads
from typing import TypeVar, Callable, Any, Optional, Dict, Union 


Handler = TypeVar("Handler", bound=Callable[[Any], None])

class Subscriber:
    """Decorate topic handlers. Must register the subscriber with register_subscriber."""

    def __init__(self) -> None:
        self.handlers: Dict[str, tuple] = dict()

    def topic(
        self, topic: str, 
        parse_func: Optional[Callable[[Union[str, bytes]], Any]] = loads
    ) -> Callable[[Handler], Handler]:
        """Subscribe to mqtt topic. by default the response is parsed with json.loads and passed into the handler.
        Override this with a custom parser or set it to None to receive the raw response."""

        def add_handler(handler: Handler) -> Handler:
            self.handlers[topic] = (handler, parse_func)
            return handler

        return add_handler

我在另一个文件中导入和使用这个类。

from typing import Union
from from organization.namespace.package.mqtt.client import Subscriber

paho: Subscriber = Subscriber()

@paho.topic("test")
def test(payload: Union[dict, list]) -> None:
    print(payload)

但我无法摆脱这个错误。

Untyped decorator makes function "handler" untypedmypy(error)

正如我们在@AlexWaygood 的帮助下发现的那样,在同一文件中使用它时不会引发此错误。但由于某种原因,当导入另一个文件时,如上所示。

我的项目具有以下目录结构:

organization
└── namespace
    └── package
        └── mqtt
            ├── client.py
            └── handler.py

__init__.py我的目录或子目录中目前没有文件。

标签: pythonpython-decoratorstype-hintingmypypython-typing

解决方案


这个问题与模块系统有关。这个问题有两种不同的解决方案:

  1. __init__.py在每个文件夹中创建一个。
  2. 运行 mypy 时使用选项--namespace-packages--explicit-package- bases。

有关更多详细信息,请参阅我在此处此处创建的 mypy 问题。


推荐阅读