Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python setter也返回一个值_Python_Python 3.x_Decorator_Setter_Getter Setter - Fatal编程技术网

Python setter也返回一个值

Python setter也返回一个值,python,python-3.x,decorator,setter,getter-setter,Python,Python 3.x,Decorator,Setter,Getter Setter,我想知道是否有可能让一个属性设置程序也返回一个值。下面的代码试图从表面上解释这个问题 基本上,我需要为一个对象设置一个属性,但在检查它是否唯一之前。我想知道是否有一种方法可以直接将唯一的名称返回给用户,而不需要在之后查询对象的新名称 class MyClass(object): def __init__(self,ID): self._ID = ID @property def Name(self): return DBGetName(se

我想知道是否有可能让一个属性设置程序也返回一个值。下面的代码试图从表面上解释这个问题

基本上,我需要为一个对象设置一个属性,但在检查它是否唯一之前。我想知道是否有一种方法可以直接将唯一的名称返回给用户,而不需要在之后查询对象的新名称

class MyClass(object):
    def __init__(self,ID):
        self._ID = ID
    @property
    def Name(self):
        return DBGetName(self._ID)

    @Name.setter
    def Name(self, value):
        UniqueName = DBGetUniqueName(self._ID,value)
        return DBSetName(UniqueName)

Myinstance = MyClass(SomeNumber)
#What I do now
Myinstance.Name = "NewName"
Uniquename = Myinstance.Name

#What I was wondering if possible. Line below is syntactically invalid, but shows the idea.
Name = (Myinstance.Name = "NewName")
编辑: 这是一个伪代码,我忘记了将值传递给内部函数。我的错。

setter当然可以返回值

但这样做并不是很有用,因为setter通常在赋值语句中使用,如您的示例中所示

问题是在Python中,赋值不是表达式,而是语句。它没有可以使用的值,并且不能将其嵌入到其他语句中。所以,没有办法写出你想写的行

您可以显式地调用setter…但是在这种情况下,只将其作为常规方法而不是属性setter编写会更清楚


在你的情况下,我认为常规方法正是你想要的。您完全忽略了传递给setter的值。这会让代码的读者感到困惑(包括6个月后的你)。它根本不是一个真正的setter,而是一个创建唯一名称的函数。那么,为什么不这样称呼呢

def CreateUniqueName(self):
    UniqueName = DBGetUniqueName(self._ID)
    return DBSetName(UniqueName)
(值得注意的是,
DBSetName
返回其参数本身并不是非常Pythonic的…)


如果您想知道Python为什么会这样工作,请参阅官方常见问题解答


更一般地说,表达式语句的区别,加上相关的功能,如变异方法(例如,
list.sort
)返回
None
,而不是
self
,导致了一种更简单、更规则的语言。当然,这是有代价的,因为这会导致语言的不流利。这是一个明显的折衷,Python已经达到了极限。(与JavaScript相比,JavaScript可能会达到相反的极端。)但大多数喜欢Python的人认为它做出了正确的权衡。

我从一个类似的问题开始,但我只需要从setter获取“通用”信息,以便自动化GUI创建;GUI代码查看属性列表,找到具有setter的属性,然后创建输入字段。但是,有些输入是字符串,有些是浮动等,GUI代码生成适当的输入字段。我知道这是一个难题,但我把这些信息放在文档字符串中以供获取

我意识到这不是你问题的答案,但可能会帮助那些看起来像我的人

class Dog():
    def __init__(self):
        self._name = None
        return
    @property
    def name(self):
        """Doggos are the best!"""
        return self._name
    @name.setter
    def name(self, n):
        self._name = n
        return
def main():
    terrier = Dog()
    terrier.name = "Rover"
    print("Dog's name is ", terrier.name)
    print(type(terrier).name.__doc__)
    # also works with...
    print(getattr(type(terrier), 'name').__doc__)
    return
if __name__ == '__main__':
    main()

我对此有点困惑。看起来setter完全忽略了您传递给它的值。一个setter,它接受了
MyInstance.Name=“NewName”
并将名称设置为
“NewName-071839”
,我可以理解,但这会让我感到困惑(即使是在JavaScript或C#或其他允许它的语言中)。嗯,从语法上讲,执行
Name=MyInstance.Name=“NewName”
是有效的,但是setter的返回值将被忽略,它只需将
Name
设置为
“NewName”
@Aya:Good point。如果没有括号,这将是一个链式赋值语句,意思是“将此值分配给所有链式名称”。在非常简单的情况下,这与C/JS/etc的操作相同。“将此值指定给姓氏,然后将该赋值的结果指定给它前面的那个,…”,但在这种情况下,这没有帮助。@abarner不确定。但是,如果你来自C++背景,并且你使用了<代码>运算符=/COD>,你可能期望能够在Python中做类似的事情。TBH,我很高兴你不能在Python中使用赋值作为表达式-我仍然偶尔将
if foo==1
误键入
if foo=1
,特别是当我在Python和SQL编码之间切换时,Python为我发现了那个特定的错误,这很好,因为它很容易被忽略。@Aya:另一个优点。链式赋值在两种可能的新手混淆方式中与C++类似,而不仅仅是C和JS的一种方式……无论如何,我也很高兴Python不允许赋值表达式,但更多的是成为一组完整的特征,使几乎所有的Python代码都比几乎任何JS或C++代码都更容易读。我也同意这会使代码难以阅读,但我很好奇这是否可能。从Python3.8开始,这个答案不再是最新的,Python3.8支持在表达式中使用赋值。walrus操作符不支持属性,包括属性。