【问题标题】:Python how to avoid "side effect"Python如何避免“副作用”
【发布时间】:2021-02-14 11:55:52
【问题描述】:

听说下面的代码是侧面有效的python代码, 因为计数列表更改 def count_case() 并且没有按我预期的那样工作。 副作用是函数对其隐式上下文所做的更改。

def main():
    word_list = ['hELLo', '', 'C7pX4%']
    counts = [0, 0]
    for word in word_list:
        count_case(word, counts)
        print('Word:', word)
        print('Lowercase count: ', counts[0])
        print('Uppercase count: ', counts[1])

def count_case(string, counts):
    for letter in string:
        if letter.islower():
            counts[0] = counts[0] + 1
        if letter.isupper():
            counts[1] = counts[1] + 1
main()

所以,我将代码更改如下。

def main():
    word_list = ['hELLo', '', 'C7pX4%']
    for word in word_list:
        counts = count_case(word, counts=[0, 0])
        print('Word:', word)
        print('Lowercase count: ', counts[0])
        print('Uppercase count: ', counts[1])

def count_case(string, counts):
    for letter in string:
        if letter.islower():
            counts[0] = counts[0] + 1
        if letter.isupper():
            counts[1] = counts[1] + 1
    return counts
main()

然后,它运作良好,但我仍然想知道 1)它是否有副作用。我想知道2)如何避免副作用。

【问题讨论】:

  • 1.是的,它仍然有副作用。 2.也许count_case应该创建自己的列表来返回?然后调用者负责汇总每次调用的结果。
  • 您是否有机会从 C 背景进入 Python(通常向函数传递指向旨在收集结果的数组的指针)?将0 列表传递给函数只是为了让该函数用实际数据替换那些零似乎很奇怪。这样做的动机是什么?为什么要通过counts?对于这种特殊情况,我会完全删除一个列表,只让函数返回一对计数:return lower, upper
  • 总之,纯函数only返回一个结果;它不会修改其输入参数或环境中的任何其他内容。显而易见且直接的好处是,您可以看到代码做了什么,而无需检查它调用的每个函数来检查它是否做了比显而易见的事情更多的事情。

标签: python side-effects


【解决方案1】:

我将通过使用对象解构和内部函数以下列方式进行:

def main():
    word_list = ['hELLo', '', 'C7pX4%']
    for word in word_list:
        lowers, uppers = count_case(word)
        print('Word:', word)
        print('Lowercase count: ', lowers)
        print('Uppercase count: ', uppers)

    def count_case(string):
        lowers = 0
        uppers = 0
        for letter in string:
           if letter.islower():
               lowers = lowers + 1
           if letter.isupper():
               uppers = uppers + 1
        return lowers, uppers
main()

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 2021-11-16
    • 2021-11-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    相关资源
    最近更新 更多