Python 中是否有一个函数与等于运算符做同样的事情

Is there a function in Python that does the same thing as the equals operator

由于我目前对 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方法的验证码。它更加模块化。问题是这样的程序不会 运行 因为 lambda 不能使用运算符。

错误是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 中是否有内置方法来执行此操作?如果没有,是否可以轻松编写一个方法?一个可以将变量作为输入并将 exact 变量设置为一个新值,而不是它的本地副本的方法?

你可以使用 global,像这样:

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

myfunc("x", "great")

print("Python is " + x)

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

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

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 built-in 函数,它可以满足您的要求:

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)

所以,您使用的术语 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!

注意,这可以是re-used各种类,如果你想模块化的话非常灵活。看看客户端代码有多cleaner,如果你想用你的逻辑设置一个属性,你就做self.attribute = value,同样,如果你想获取一个属性,你只要做 self.attribute。到处都没有丑陋的 set_attribute()get_attribute()

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

Descriptor HOWTO