【问题标题】:Python: get_owner_by_number_input_value1() got multiple values for argument 'self'Python:get_owner_by_number_input_value1() 为参数“self”获取了多个值
【发布时间】:2021-12-01 15:40:48
【问题描述】:

在我将此代码转移到类之前,get_owner_by_number_input_value1 工作正常,但在类中,现在它不起作用并给出错误“get_owner_number_input_value1 () Got Multiple Values for Argument 'Self'”,现在只有带有 get_owner_by_number_input_value2 的选项.我不明白这是什么错误,我看起来像类似的问题,并没有发现与我的相似之处。头疼,用了一堆时间,但没有任何意义。大请求帮助,因为我不知道该做什么以及在哪里联系)

import inspect


documents = [
    {"type": "passport", "number": "2207 876234", "name": "Gloria", },
    {"type": "invoice", "number": "11-2", "name": "Jack Nickolas", },
    {"type": "insurance", "number": "10006", "name": "John", }
]

class DocumentManager:
    def __init__(self, doc):
        self._documents = doc

    def input_arguments_with_prompts(*prompts):
        def decorator(func):
            def wrapper(*args, **kwargs):
                parameters = inspect.signature(func).parameters
                for prompt, (name, parameter) in zip(prompts, parameters.items()):
                    while True:
                        value = input(prompt)
                        if parameter.annotation is inspect._empty:
                            converted_value = value
                            break
                        try:
                            converted_value = parameter.annotation(value)
                        except ValueError:
                            pass
                        else:
                            break
                    kwargs[name] = converted_value
                return func(*args, **kwargs)
            return wrapper
        return decorator

    def get_owner_by_number(self, number: str) -> str:
        for document in self._documents:
            if document["number"] == number:
                return document["name"]
        return ""

    @input_arguments_with_prompts(
        "Enter the document number, the owner of which you want to get: ",
    )
    def get_owner_by_number_input_value1(self, input_number: str):
        return self.get_owner_by_number(input_number)

    def get_owner_by_number_input_value2(self):
        input_number = input('Enter number')
        return self.get_owner_by_number(input_number)

dm = DocumentManager(documents)
dm.get_owner_by_number_input_value1()

【问题讨论】:

  • 你试过把装饰器移到课堂外吗?如果你还没看过:stackoverflow.com/questions/11740626/…
  • @PM77-1 是的,我在课堂内外都尝试过 self 。错误是一样的,但是当在类中指定 self 时,它会抛出一个错误,即缺少所需的 input_number 参数

标签: python python-3.x


【解决方案1】:

这并不完美,因为显然 you can't detect whether a function is in a class,但您可以使用启发式方法来检查这种情况,并希望此装饰器的用户遵循为类中的方法命名第一个参数 "self" 的约定。

import inspect


documents = [
    {"type": "passport", "number": "2207 876234", "name": "Gloria", },
    {"type": "invoice", "number": "11-2", "name": "Jack Nickolas", },
    {"type": "insurance", "number": "10006", "name": "John", }
]

def input_arguments_with_prompts(*prompts):
    def decorator(func):
        def wrapper(*args, **kwargs):
            parameter_list = list(inspect.signature(func).parameters.items())
            if parameter_list[0][0] == "self":
                parameter_list = parameter_list[1:]
            for prompt, (name, parameter) in zip(prompts, parameter_list):
                while True:
                    value = input(prompt)
                    if parameter.annotation is inspect._empty:
                        converted_value = value
                        break
                    try:
                        converted_value = parameter.annotation(value)
                    except ValueError:
                        pass
                    else:
                        break
                kwargs[name] = converted_value
            return func(*args, **kwargs)
        return wrapper
    return decorator

class DocumentManager:
    def __init__(self, doc):
        self._documents = doc

    def get_owner_by_number(self, number: str) -> str:
        for document in self._documents:
            if document["number"] == number:
                return document["name"]
        return ""

    @input_arguments_with_prompts(
        "Enter the document number, the owner of which you want to get: ",
    )
    def get_owner_by_number_input_value1(self, input_number: str):
        return self.get_owner_by_number(input_number)

    def get_owner_by_number_input_value2(self):
        input_number = input('Enter number')
        return self.get_owner_by_number(input_number)

dm = DocumentManager(documents)
print(dm.get_owner_by_number_input_value1())

如果您也想支持类方法,您可以将检查更改为if parameter_list[0][0] in {"self", "cls"}。我链接的答案中还有一个启发式方法,用于检查方法的限定名称中是否有.,因此您也可以根据需要添加它。

【讨论】:

  • 再次你好)这个问题有点跑题了,但是有了这样的实现,我就做不到了,例如,如果函数中的参数need_input = True,则执行装饰器, 如果 False 没有被执行。 pastebin.com/72aFvGME我这样做了,但是它根本没有反应,无论我在调用函数时指定什么参数need_input,只会取函数声明时指定的那个
  • 也许将其作为一个单独的问题提出,以便引起更多关注?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 2021-09-20
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 2019-01-03
相关资源
最近更新 更多