类型铸造(相同类型的多个参数)

发布于 2025-01-26 05:57:14 字数 801 浏览 3 评论 0 原文

我有以下方法声明:

def method(alpha, size=10, logged_in=False, interactions=False):
    
    if not isinstance(logged_in, bool):
        logged_in = str(logged_in).lower() in ['true']
    
    if not isinstance(interactions, bool):
        interactions = str(interactions).lower() in ['true']

如果需要语句,则是因为 Interactions 将错误地设置为 true 如果我通过互动=“ false” 作为参数(因此,我传递了一个字符串)。虽然以上解决方案,但我想知道是否有一种更优雅的方法来实现它(请注意,我有很多布尔参数, logged_in and 互动,以及我也有一些 float 参数。我做一个一般的(即,支持 bool float int string )?到 this 问题可能有可能有用,但仍然想检查是否有更好的方法。

I have the following method declaration:

def method(alpha, size=10, logged_in=False, interactions=False):
    
    if not isinstance(logged_in, bool):
        logged_in = str(logged_in).lower() in ['true']
    
    if not isinstance(interactions, bool):
        interactions = str(interactions).lower() in ['true']

The if statements are needed because, for example, interactions would be falsely set to True if I pass interaction="False" as a parameter (so, I pass a String). While the above does the trick, I wonder if there is a more elegant way to achieve it (note that I have a lot of boolean parameters, beside logged_in and interactions, and I also have some int and float parameters. How could decorators be used here? Could one decorator be used for all bool parameters, and how could I make a general one (i.e., supporting bool, float, int, string)? I found the answer to this question potentially useful, but still wanted to check if there are better ways.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

想你的星星会说话 2025-02-02 05:57:14

您可以尝试这样的事情。

def bool_fixer(func):
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str) and val.lower() in table:
                kwargs[key] = table[val.lower()]
        return func(*args, **kwargs)
    return wrapper

@bool_fixer
def method(...):
    do something

在装饰仪做魔术之后,所有字符串“ true”和“ false”都将变成他们的python bool 等效,您可以跳过 method>方法函数中的所有检查。

如果您要它覆盖 ints floats 也:

import re
def converter(func):
    patterns = {r"\d*": int, r"\d*?\.\d*": float}
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str):
                if val.lower() in table:
                    kwargs[key] = table[val.lower()]
                    continue
                for pattern in patterns:
                    if re.match(pattern, val):
                        kwargs[key] = patterns[pattern](val)
        return func(*args, **kwargs)
    return wrapper

def converter(func):
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str):
                if val.lower() in table:
                    kwargs[key] = table[val.lower()]
                elif val.isdigit():
                    kwargs[key] = int(val)
                elif re.match(r"\d*?\.\d*", val):
                    kwargs[key] = float(val)
        return func(*args, **kwargs)
    return wrapper

You could try something like this.

def bool_fixer(func):
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str) and val.lower() in table:
                kwargs[key] = table[val.lower()]
        return func(*args, **kwargs)
    return wrapper

@bool_fixer
def method(...):
    do something

after the decorator does its magic then all of the string "true" and "false" will turn into their python bool equivalent and you can skip all the checking in the method function.

If you want it to cover ints and floats too:

import re
def converter(func):
    patterns = {r"\d*": int, r"\d*?\.\d*": float}
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str):
                if val.lower() in table:
                    kwargs[key] = table[val.lower()]
                    continue
                for pattern in patterns:
                    if re.match(pattern, val):
                        kwargs[key] = patterns[pattern](val)
        return func(*args, **kwargs)
    return wrapper

or

def converter(func):
    table = {"true": True, "false": False}
    def wrapper(*args, **kwargs):
        for key, val in kwargs.items():
            if isinstance(val, str):
                if val.lower() in table:
                    kwargs[key] = table[val.lower()]
                elif val.isdigit():
                    kwargs[key] = int(val)
                elif re.match(r"\d*?\.\d*", val):
                    kwargs[key] = float(val)
        return func(*args, **kwargs)
    return wrapper
天涯沦落人 2025-02-02 05:57:14

该装饰器应可靠地处理布尔,ints和浮标。如书所编写,这将修改str类型的关键字参数。它首先检查一下str是“ [tt] rue”或“ [ff] alse”的单词。下一个测试是检查STR是否是整数(简单的铸造测试)。首先检查int是因为格式比浮点更具体,因为int必须仅是数字,但是float可以包含小数点。最后,它试图漂浮。如果所有这些演员都失败了,那么我们假设这是一个不应被篡改的实际str。

def cast_arguments(method):
    """decorator"""

    def wrapper(*args, **kwargs):
        for key, value in kwargs.items():

            # change special strings to bools
            if isinstance(value, str):
                if value.lower() == "true":
                    kwargs[key] = True
                elif value.lower() == "false":
                    kwargs[key] = False
                else:
                    try:
                        # change ints to int (int cannot have ".")
                        kwargs[key] = int(value)
                    except ValueError:
                        try:
                            # change floats to float (can have ".")
                            kwargs[key] = float(value)
                        except ValueError:
                            # this is an actual string
                            pass

        return method(*args, **kwargs)
    return wrapper


class Test:
    @cast_arguments
    def method(self, logged_in=False, interactions=False, other=False):
        print("logged_in: ", logged_in, type(logged_in))
        print("interactions: ", interactions, type(interactions))
        print("other: ", other, type(other))


c = Test()
c.method(logged_in="1", interactions="True", other="3.14")

输出:

$ python test.py
logged_in:  1 <class 'int'>
interactions:  True <class 'bool'>
other:  3.14 <class 'float'>

This decorator should reliably handle bools, ints and floats. As written this will modify keyword arguments that are str type. It first checks to see if the str is the words "[Tt]rue" or "[Ff]alse". The next test is checking to see if the str is an integer (a simple cast test works). Int is checked first because the formatting is more particular than float, since int must be only numbers, but float can contain decimal points. Finally, it tries a cast to float. If all of these casts fail, then we assume it is an actual str that shouldn't be tampered with.

def cast_arguments(method):
    """decorator"""

    def wrapper(*args, **kwargs):
        for key, value in kwargs.items():

            # change special strings to bools
            if isinstance(value, str):
                if value.lower() == "true":
                    kwargs[key] = True
                elif value.lower() == "false":
                    kwargs[key] = False
                else:
                    try:
                        # change ints to int (int cannot have ".")
                        kwargs[key] = int(value)
                    except ValueError:
                        try:
                            # change floats to float (can have ".")
                            kwargs[key] = float(value)
                        except ValueError:
                            # this is an actual string
                            pass

        return method(*args, **kwargs)
    return wrapper


class Test:
    @cast_arguments
    def method(self, logged_in=False, interactions=False, other=False):
        print("logged_in: ", logged_in, type(logged_in))
        print("interactions: ", interactions, type(interactions))
        print("other: ", other, type(other))


c = Test()
c.method(logged_in="1", interactions="True", other="3.14")

output:

$ python test.py
logged_in:  1 <class 'int'>
interactions:  True <class 'bool'>
other:  3.14 <class 'float'>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文