python 使用 lambda getter 和 setter 创建属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1224962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:43:46  来源:igfitidea点击:

Create properties using lambda getter and setter

pythonlambdaproperties

提问by tefozi

I have something like this:

我有这样的事情:

class X():
    def __init__(self):
        self.__name = None

    def _process_value(self, value):
        # do something
        pass

    def get_name(self):
        return self.__name

    def set_name(self, value):
        self.__name = self._process_value(value)

    name = property(get_name, set_name)

Can I replace get_nameand set_nameusing lambda functions?

我可以替换get_nameset_name使用 lambda 函数吗?

I've tried this:

我试过这个:

name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value))

but compiler doesn't like my setter function.

但是编译器不喜欢我的 setter 函数。

回答by Alex Martelli

Your problem is that lambda's body must be an expression and assignment is a statement (a strong, deep distinction in Python). If you insist on perpetrating lambdas you'll meet many such cases and learn the workarounds (there's usually one, though not always), such as, in this case:

您的问题是 lambda 的主体必须是一个表达式,而赋值是一个语句(Python 中的一个强大而深刻的区别)。如果您坚持执行lambdas,您将遇到许多此类情况并了解解决方法(通常有一种,但并非总是如此),例如,在这种情况下:

name = property(lambda self: self.__name, 
                lambda self, value: setattr(self, 
                                            '_X__name',
                                            self.process_value(value)))

i.e. use the built-in setattr(which is a function and thus acceptable in a lambda's body) rather than assignment (which is a statement and thus unacceptable in a lambda's body).

即使用内置的setattr(它是一个函数,因此在 alambda的主体中是可以接受的)而不是赋值(这是一个语句,因此在 alambda的主体中是不可接受的)。

You also need to perform the name-mangling for the dual-underscore attribute manually (changing __nameto _X__nameas you're in class X) where the attribute name is presented as a quoted string, as it must be in setattr, as the Pyhon compiler only does the name mangling in question for suitable identifiers, not for string literals.

您还需要进行名称重整手动双下划线属性(改变__name_X__name如你在类X)其中属性名是作为一个引用的字符串,因为它必须是setattr,作为Pyhon编译器只不为合适的标识符而不是字符串文字进行有问题的名称重整。

回答by Philipp Kewisch

If you are extending a list, you can also use __setitem__, like this:

如果您要扩展 a list,您还可以使用__setitem__,如下所示:

class Position(list):
    def __init__(self,x=0, y=0, z=0):
        super(Position, self).__init__((x,y,z))

    x = property(lambda self: self[0],
                 lambda self,value: self.__setitem__(0, value))
    y = property(lambda self: self[1],
                 lambda self,value: self.__setitem__(1, value))
    z = property(lambda self: self[2],
                 lambda self,value: self.__setitem__(2, value))