Skip to main content
 首页 » 编程设计

Python之Property Getter 作为带有参数的 lambda

2025年05月04日14hnrainll

作为 python 的新手,我刚刚遇到 property 关键字,它基本上可以让您分配 getter 和 setter。我想到了这个简单的例子

class foo: 
    def __init__(self,var=2): 
        self.var= var 
 
    def setValue(self,var): 
        print("Setting value called") 
        self._var  = var 
 
    def getValue(self): 
        print("getting value") 
 
    var = property(getValue,setValue) 

现在在我的 django 项目中我遇到了这样的事情(在属性中使用 lambda)

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    likes_cheese = models.BooleanField(default=True) 
    puppy_name = models.CharField(max_length=20) 
 
User.profile = property(lambda u : UserProfile.objects.get_or_create(user=u)[0]) 

我不知道您可以在属性中使用 lambda。现在据我了解,它将 profile 的 getter 设置为 lambda,并且 getter 需要一个参数。这让我很困惑。所以我决定尝试我自己的例子

class double: 
    def setValue(self,var): 
        print("Setting value called") 
        self._var  = var 
 
    def getValue(self): 
        print("getting value") 
 
    #var = property(getValue,setValue) 
    var = property(lambda x: print("The value of parameter is" + str(x))) 
 
d =double() 
d.var #Call the getter but how do i pass a value parameter to it ?  

现在在我的例子中,我如何将参数传递给 lambda?

请您参考如下方法:

编写属性的正常/惯用方式是:

class MyClass(object): 
    def __init__(self): 
        self._foo = 42 
 
    @property 
    def foo(self): 
        return self._foo 
 
    @foo.setter 
    def foo(self, val): 
        self._foo = val 

如您所见,与 Python 中的所有其他方法定义一样,该方法的第一个参数是 self。

您可以随意命名参数(不要!),但第一个参数始终是对象本身。

上面的漂亮语法可以解构为

class MyClass(object): 
    def __init__(self): 
        self._foo = 42 
 
    def foo_get(self): 
        return self._foo 
 
    def foo_set(self, val): 
        self._foo = val 
 
    foo = property(foo_get, foo_set) 

我们可以使用 lambdas 而不是将函数 names 传递给 property:

class MyClass(object): 
    def __init__(self): 
        self._foo = 42 
 
    def foo_set(self, val): 
        self._foo = val 
 
    foo = property(lambda self: self._foo, foo_set) 

我们不能将 setter 作为 lambda 传递,因为 lambda 不能包含赋值。在这里,我继续使用 self 作为参数名称,但我可以使用任何变量名称,例如:

foo = property(lambda u: u._foo, foo_set)