在Python中,具有映射字典的工厂类返回TypeError。

huangapple go评论64阅读模式
英文:

Factory class in Python with a mapping dictionary returns TypeError

问题

我创建了类似这样的虚拟类:

class CreateCaseFactory:
    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(user_id)
        else:
            raise Exception("Invalid type")

    @classmethod
    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 1 created for user {user_id}"
        return result

    @classmethod
    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 2 created for user {user_id}"
        return result

CASE_TO_METHOD_MAP = {
    "case_1": _create_case_1,
    "case_2": _create_case_2,
}

但是当我尝试运行它时出错:

if creator:
    return creator(user_id)
E TypeError: 'classmethod' object is not callable

如何让这个工厂类工作?

英文:

I made something like this dummy class:

class CreateCaseFactory:
    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(user_id)
        else:
            raise Exception("Invalid type")

    @classmethod
    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 1 created for user {user_id}"
        return result

    @classmethod
    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 2 created for user {user_id}"
        return result

    CASE_TO_METHOD_MAP = {
        "case_1": _create_case_1,
        "case_2": _create_case_2,
    }

but I get an error when I try to run it:

        if creator:
>           return creator(user_id)
E           TypeError: 'classmethod' object is not callable

How can I make this factory class work.

答案1

得分: 0

你正在尝试调用创建者对象,它是一个类方法。在Python中,类方法不能直接像常规函数一样调用。

示例:

import uuid

class CreateCaseFactory:

    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(cls, user_id)  # 使用类本身调用类方法
        else:
            raise Exception("无效的类型")

    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"为用户 {user_id} 创建了虚拟用例1"
        return result

    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"为用户 {user_id} 创建了虚拟用例2"
        return result

    CASE_TO_METHOD_MAP = {
        "case_1": _create_case_1,
        "case_2": _create_case_2,
    }

uuid1 = uuid.UUID("12345678-1234-5678-1234-567812345678")
factory = CreateCaseFactory()
case_1 = factory.create(user_id=uuid1, type_="case_1")
print(case_1)
# 为用户 12345678-1234-5678-1234-567812345678 创建了虚拟用例1

请注意,已经将代码中的 HTML 实体字符 (>") 替换为相应的符号。

英文:

You are trying to call the creator object, which is a class method. In Python, class methods are not directly callable as regular functions.
Example

import uuid


class CreateCaseFactory:

    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(cls, user_id)  # Call the class method using the class itself
        else:
            raise Exception("Invalid type")

    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 1 created for user {user_id}"
        return result

    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 2 created for user {user_id}"
        return result

    CASE_TO_METHOD_MAP = {
        "case_1": _create_case_1,
        "case_2": _create_case_2,
    }


uuid1 = uuid.UUID("12345678-1234-5678-1234-567812345678")
factory = CreateCaseFactory()
case_1 = factory.create(user_id=uuid1, type_="case_1")
print(case_1)
# Dummy Use Case 1 created for user 12345678-1234-5678-1234-567812345678

答案2

得分: 0

如错误消息所示,classmethod 的实例不可调用。当您使用类似 CreateCaseFactory.create(...) 的方式调用类方法时,描述符协议会从类方法中“提取”底层函数,并将其作为第一个参数与 CreateCaseFactory 一起调用。

create_case_1_create_case_2 不应该是类方法,而应该是常规函数。

class CreateCaseFactory:
    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(cls, user_id)
        else:
            raise Exception("Invalid type")

    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 1 created for user {user_id}"
        return result

    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 2 created for user {user_id}"
        return result

    CASE_TO_METHOD_MAP = {
        "case_1": _create_case_1,
        "case_2": _create_case_2,
    }
英文:

As the error message says, instances of classmethod are not callable. When you call a class method with something like CreateCaseFactory.create(...), the descriptor protocol "extracts" the underlying function from the class method and calls it with CreateCaseFactory as the first argument.

create_case_1 and _create_case_2 should not be class methods, but regular functions.

class CreateCaseFactory:
    @classmethod
    def create(cls, user_id: uuid.UUID, type_: str) -> str:
        creator = cls.CASE_TO_METHOD_MAP.get(type_)
        if creator:
            return creator(cls, user_id)
        else:
            raise Exception("Invalid type")

    def _create_case_1(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 1 created for user {user_id}"
        return result

    def _create_case_2(cls, user_id: uuid.UUID) -> str:
        result = f"Dummy Use Case 2 created for user {user_id}"
        return result

    CASE_TO_METHOD_MAP = {
        "case_1": _create_case_1,
        "case_2": _create_case_2,
    }

huangapple
  • 本文由 发表于 2023年6月1日 20:49:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76382044.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定