成为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?
答案 0 :(得分:5)
编写属性的正常/自动方式是:
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)
而不是将函数名称传递给property
而不是使用lambdas:
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传递,因为lambdas不能包含赋值。在这里,我继续使用self
作为参数名称,但我可以使用任何变量名称,例如:
foo = property(lambda u: u._foo, foo_set)
答案 1 :(得分:1)
你可能想做这样的事情。
class double:
def __init__(self):
self._var = None
var = property(lambda self: self._var,
lambda self, value: setattr(self, "_var", value))
d = double()
d.var = 3
print(d.var)
使用绑定方法时,传递给它们的第一个参数始终是类的实例。在绝大多数情况下,它被命名为self
。但这只是一个惯例,你可以随心所欲地命名,所以当你这么做时
var = property(lambda x: print("The value of parameter is" + str(x)))
x
指向该实例,str(x)
类似于<__main__.double object at 0x105f47a90>
,这显然不是您想要的。
其次,getter不接受任何其他参数,因为......好吧,除了实例之外你真的不需要任何其他东西。
第三,我们也可以使用lambda作为制定者;我们在这里需要2个参数,实例和值,但lambda不能包含赋值,所以我们必须使用setattr()
函数来解决它。
但如果这种方法不仅仅用于训练和探索,我建议使用@thebjorn所示的@property
语法。