理解python

时间:2018-04-10 01:34:47

标签: python

我正在学习列表的方法(pop和remove之间的区别)
并注意Command–query separation

  

它声明每个方法应该是执行操作的命令,或者是将数据返回给调用者的查询,而不是两者。换句话说,提出问题不应该改变答案。 [1]更正式地说,方法只有在它们是引用透明的情况下才会返回一个值,因此没有副作用。

我无法解释“提出问题不应该改变答案”,
我读了ppt 维基百科链接,其中以通道内外的“轻”标志为例 它没有说明问题和答案之间的关系。

在我看来,它应该是“回答一个问题不应该改变问题”
这是合理的说法

  

从理论上讲,这确立了一种理智的度量,从而可以在不同时修改该状态的情况下推理程序的状态。

我的演绎是否合理?

3 个答案:

答案 0 :(得分:1)

你已经掌握了它的要点。在计算机科学术语中,它几乎意味着获取信息不应以任何方式修改信息

他们的意思

  

更正式地说,方法只有在引用透明的情况下才能返回值,因此没有副作用。

更多地与您的软件和客户之间的通信有关。这进一步说明了返回的任何信息必须是实际存储值的副本,并且不能用于以任何方式追溯到该值。

以此列表为例:

a = [1, 2, 3, 4, 5]

这是我系统中一个非常重要的列表,客户付钱给我访问我的秘密列表。我将在这里编写一个方法,并说send()方法会将此列表发送给我的客户。

如果我send(a)给我的客户,这打破了上面的原则。因为现在我的客户端可以使用引用中的一些令人讨厌的说法:

for i in range(len(a)):
    a[i] = None

现在,当我尝试访问a时,我得到的只是[None, None, None, None, None]。它们被覆盖了,因为我发送了它们而不是值。相反,我应该有send(a[:])或者副本。现在无论我的客户对我发送给他的列表做了什么,它对我系统内部的内容都没有影响。

答案 1 :(得分:0)

以下课程遵守CQS原则。它的每个方法都是查询或命令。方法get提供有关状态的信息,并且不允许任何副作用。方法set具有副作用,因此返回None

class IntValue:
    def __init__(self, x):
        self.x = int(x)

    def get(self):
        return self.x

    def set(self, x):
        self.x = int(x)

特别是,以下情况永远如此。

v = IntValue(1)

v.get() == v.get() # Always True

您永远不会通过get方法询问值并同时更改它。在这里,CQS原则向您保证,您可以连续多次询问该值并仍然获得相同的答案

这一点很重要的原因是因为程序中出现了很多不受欢迎的复杂因素。

现在考虑一个封装列表的类似类。

class ListValue:
    def __init__(self, x):
        self.x = list(x)

    def get(self):
        return self.x

    def set(self, x):
        self.x = list(x)

上述问题是提出问题可能会导致答案改变。

v = ListValue([1, 2, 3])

lst = v.get() # [1, 2, 3]

lst.append(4)

v.get() # [1, 2, 3, 4]

在开发大型软件时,这通常是难以跟踪的错误的来源。通过确保您无法从ListValue访问状态,但只能查看该状态的视图,可以避免这些情况。

class ListValue:
    def __init__(self, x):
        self.x = list(x)

    def get(self):
        return deepcopy(self.x) # Here we return a copy of the list

    def set(self, x):
        self.x = list(x)

答案 2 :(得分:0)

  

我无法解释“提出问题不应该改变答案”,   我阅读了ppt wikipedia链接,它以频道内外的“轻”标志为例。它没有说明问题和答案之间的关系。

Light?基本上问“灯亮吗?”它返回True或False。

Light?做错的事情是,如果它关闭则打开灯,或者如果它打开则关灯。在没有任何其他混淆代码的情况下,连续执行Light?三次应返回相同的值三次。 提出问题不应该改变答案。但如果问Light?问题改变了答案,你会得到“真,假,真”或“假,真,假”。

  

在我看来,它应该是“回答一个问题不应该改变问题”

不,因为答案(返回值)无法更改问题(方法调用)。但问题可以改变答案(如果你用这种方式编写方法)。