首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型错误:“可调用[[VarArg(Any),KwArg(Any)],Any]”没有属性*

类型错误:“可调用[[VarArg(Any),KwArg(Any)],Any]”没有属性*
EN

Stack Overflow用户
提问于 2022-03-16 12:54:10
回答 1查看 752关注 0票数 0

我正在定义一个类,如果没有声明color实例属性,则根据接收的调用数自动设置它。

在下面,您可以看到一个最小的工作示例:

代码语言:javascript
复制
from typing import Callable
import itertools
from plotly.express import colors as px_colors
COLOR_LIST = px_colors.qualitative.Alphabet

# Decorator
def color_setter(func: Callable):
    """Counts how many times `~MyClass` has been called and sets the
    instance color accordingly.

    Parameters
    ----------
    func : Callable

    Returns
    -------
    Callable
    """

    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        wrapper.color = next(wrapper.cycle_color_list)
        # print(f'wrapper called {wrapper.calls} times')
        return func(*args, **kwargs)
    
    wrapper.calls = 0  # Adding # type: ignore here suppresses
                       # the error, but it is not a solution...
    wrapper.cycle_color_list = itertools.cycle(COLOR_LIST)  # same here

    return wrapper

@color_setter
def _set_color(color: str) -> tuple:
    """Sets MyClass color and id.

    Parameters
    ----------
    color : str
        Color variable, can be RGBA or HEX string format.

    Returns
    -------
    tuple
        MyClass color and call id
    """
    if color is None:
        color = _set_color.color
    my_id = _set_color.calls
    return color, my_id


class MyClass():
    """Example class.
    """

    def __init__(
        self,
        color: str = None,
    ) -> None:
        """Define MyClass.

        Parameters
        ----------
        color : str, optional
            RGBS or HEX string for color, by default None
        """
        self.color, self.id = _set_color(color)

代码的行为与预期相同,但mypy返回以下两个错误,我无法解决这些错误。

代码语言:javascript
复制
example.py:26: error: "Callable[[VarArg(Any), KwArg(Any)], Any]" has no attribute "calls"
        wrapper.calls = 0
        ^
example.py:27: error: "Callable[[VarArg(Any), KwArg(Any)], Any]" has no attribute "cycle_color_list"
        wrapper.cycle_color_list = itertools.cycle(COLOR_LIST)
        ^
Found 2 errors in 1 file (checked 1 source file)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-16 18:55:16

Mypy抱怨功能属性没有被正确输入。

定义一个包装函数,它的类型为Callable[[VarArg(Any), KwArg(Any)], Any]。此类型不附带属性callscolor。因此,访问它会导致属性错误。

代码语言:javascript
复制
from typing import Callable, Optional

# Decorator
def color_setter_alt(func: Callable):
    """Counts how many times `~MyClass` has been called and sets the
    instance color accordingly.

    Parameters
    ----------
    func : Callable

    Returns
    -------
    Callable
    """

    class Wrapper:
        color: Optional[str]

        def __init__(self):
            # Wrapper is callable because it has the `__call__` method.
            # Not being a plain function allows you to explicitly define the function attributes
            self.calls = 0
            self.cycle_color_list = itertools.cycle(COLOR_LIST)

        def __call__(self, *args, **kwargs):
            self.calls += 1
            self.color = next(self.cycle_color_list)
            # print(f'wrapper called {wrapper.calls} times')
            return func(*args, **kwargs)

    return Wrapper()

另一个解决办法是使用setattrgetattr

代码语言:javascript
复制
# Decorator
def color_setter(func: Callable):
    """Counts how many times `~MyClass` has been called and sets the
    instance color accordingly.

    Parameters
    ----------
    func : Callable

    Returns
    -------
    Callable
    """

    def wrapper(*args, **kwargs):
        setattr(wrapper, "calls", getattr(wrapper, "calls") + 1)
        setattr(wrapper, "color", next(getattr(wrapper, "cycle_color_list")))
        # print(f'wrapper called {wrapper.calls} times')
        return func(*args, **kwargs)
    
    setattr(wrapper, "calls", 0) 
    setattr(wrapper, "cycle_color_list", itertools.cycle(COLOR_LIST))

    return wrapper

这种方法的优点是,您可以在以后对附加属性进行猴子修补,而不必修改原始函数。但缺点是它不能为您提供输入提示。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71497462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档