【问题标题】:Is there a function in Python that does the same thing as the equals operatorPython 中是否有与等号运算符执行相同操作的函数
【发布时间】:2020-11-24 04:45:20
【问题描述】:

由于我目前对 Python 语法的理解,我遇到了一个问题,我需要将变量设置为一个值,但不使用任何运算符。我必须使用函数。

考虑这个情景

class Senario:
    x: str = ''
    y: str = ''
    
    set_global_variable(self, set_variable, val: str)
        # some verification code and modifications
        set_variable(val)

    set_x(self, val: str)
        self.set_global_variable(setX, val)

    set_x(self, val: str)
        self.set_global_variable(lambda new_x: self.x = new_x, val)

这样设置变量的好处是添加新变量不需要为新的setter方法复制和粘贴一堆验证码。它更加模块化。问题是这样的程序无法运行,因为 lambdas 不能使用运算符。

错误是self.set_global_variable(lambda new_x: self.x --> = new_x, val)

这不是正确的语法。为了运行这样的程序,我需要某种与 = 运算符完全相同的 equals 方法。实现将按如下方式工作。

set_x(self, val: str)
    self.set_global_variable(lambda new_x: self.x.equals(new_x), val)

Python 中是否有内置方法可以执行此操作,如果仅适用于字符串?如果没有,可以轻松编写方法吗?可以将变量作为输入并将该精确变量设置为新值,而不是它的本地副本?

【问题讨论】:

  • 我很确定你想要setattr,但你的问题对我来说并不是很清楚。请注意,您可以简单地不使用 lambda 表达式和允许赋值语句的常规函数​​定义语句。
  • set_global_variable 应该做什么? 看起来您实际上想要设置一个实例变量,同样,您的示例非常混乱
  • “像这样设置变量的好处是添加新变量不需要为新的setter方法复制和粘贴一堆验证码。”你能举例说明你到底想避免什么吗?可能有更好的方法来完成您在 Python 中尝试做的事情,例如,编写自定义描述符来模块化设置器逻辑。
  • 啊,我来自 java,你所有的变量都必须在一个类中,所以我把全局变量和实例变量弄糊涂了。主要思想是我想概括一个 setter 函数,我可以轻松地使用我的所有变量重用它
  • 不,我认为 eq 返回一个布尔值 @AlexanderLekontsev

标签: python methods equals-operator


【解决方案1】:

最简单的解决方案可能是使用执行赋值的本地函数,如下所示:

def set_x(self, val: str):
    def _set_variable(new_x):
        self.x = new_x
    self.set_global_variable(_set_variable, val)

但是,如果你想使用 lambda 表达式,你可以尝试使用 python 的 setattr 内置函数,它可以满足你的要求:

def set_x(self, val: str):
    self.set_global_variable(lambda new_x: setattr(self, "x", new_x), val)

更通用的解决方案可能是将字段名称传递给set_global_variable 并使用setattr 执行分配,如下所示:

def set_global_variable(self, variable_name, val):
    # some verification code and modifications
    setattr(self, variable_name, val)

def set_x(self, val: str):
    set_global_variable("x", val)

【讨论】:

  • 我花了一点时间来理解 setattr 但是的,这就是我要找的。本质上 x = 3 与 setattr(self, "x", 3) 相同,对吧?
  • @KNOBP 个人编号。 x = 3 在你所在的范围内设置一个变量。 setattr 在一个对象上设置一个属性
  • 哎呀是的,所以首先在一个有变量的类中很重要。否则,它将不起作用。
  • 我添加了对内置 setattr 的引用。本质上,setattr(self, "x", 3)self.x = 3 相同。
  • 如果你想要更一般的赋值,也包括局部变量(出于某种原因),使用局部函数 _set_variable 的第一个解决方案对你可以在内部执行的操作类型没有限制。
【解决方案2】:

因此,您错误地使用了术语global,您只是在尝试动态设置属性。这可以通过setattr 完成,但是,您实际上 试图完成的是封装setter 逻辑。 Python 有描述符协议。以下是在 Python 中执行此类操作的方法:

class AlwaysCapitalized:
    def __get__(self, instance, owner=None):
        return getattr(instance, self.name)
    def __set__(self, instance, value):
        setattr(instance, self.name, value.capitalize())
    def __set_name__(self, owner, name):
        self.name = f"_{name}"

class MemberName:

    first_name = AlwaysCapitalized()
    last_name = AlwaysCapitalized()

    def __init__(self, first, last):
        self.first_name = first
        self.last_name = last

name  = MemberName("juan", "arrivillaga")  
print(f"Hello, {name.first_name} {name.last_name}!")

输出:

Hello, Juan Arrivillaga!

注意,这可以在各种类中重用,如果你想模块化,它非常灵活。看看客户端代码有多少cleaner,如果你想用你的逻辑设置一个属性,你只需做self.attribute = value,同样,如果你想获得一个属性,你只需做@987654327 @。到处都没有丑陋的set_attribute()get_attribute()

注意,property 对象只是描述符,classmethodstaticmethod 装饰器也是如此。实际上,函数对象只是描述符,其__get__ 方法本质上部分地将实例作为第一个参数应用于自身。

Descriptor HOWTO

【讨论】:

  • 从技术上讲,我标记为正确的答案与我尝试解决问题的方式更相关,但是,我认为这种全新的方法也值得一试。我的项目有一个我编写的后端和一个用户编写的前端,因此这将使他们更容易。即便如此,我不喜欢您不再处理字符串而是处理类对象的方式。不过,对此答案 +1!
  • @KNOBPersonal 不,您正在处理字符串。注意,我传递了字符串:MemberName("juan", "arrivillaga") 注意,字符串也是类的对象......
【解决方案3】:

您可以为此使用global,如下所示:

def myfunc(x, y):
  exec(f"global {x}”)
  exec(f"{x} = {y}")

myfunc("x", "great")

print("Python is " + x)

但是,我看到您正在创建一个 setter,使属性 y 成为全局值,这意味着您只能有 1 个(有意义的)对象 op 类型的 Scenario。

【讨论】:

  • 有没有一种方法可以将其推广到一个函数中的任何变量。前任。 set(varname: str): 全局变量名; varname =“太棒了”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 1970-01-01
  • 2011-04-14
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多