提问人:OrenIshShalom 提问时间:1/14/2021 最后编辑:jonrsharpeOrenIshShalom 更新时间:1/14/2021 访问量:476
区分只读函数输入参数和可变函数输入参数的 Python 方法
Pythonic way to distinguish read-only function input parameters from mutable ones
问:
Python 似乎没有有效的限定符 如何在 Python 中创建常量?区分只读/可变函数参数的最“pythonic”方法是什么?我应该在评论中指出吗?const
# my_graph is READ-ONLY
# my_set is added items with property X ...
def my_lovely_function(my_graph,my_set):
答:
在 C 语言和其他几种语言中,实际输出通常通过指针或引用传递的输入进行通信。这样做的原因是,许多这些范式中的返回值机制已被劫持用于错误处理目的,即返回值是成功/错误代码,而有用的输出填充在输入/指针引用中。这导致需要将一些输入表示为不可触及的 (consts),而将其他输入表示为可触摸的,以防止在使用该函数时出现混淆。
Python 通常不希望你以这种方式做事。它希望你使用 Exceptions 和 Exception 处理进行错误处理,并使用 return 语句进行实际输出。这更简洁,更符合返回值的原始想法,然后才被错误处理劫持。
在某些情况下,使用可变输入将数据传出仍然更方便。python 中的所有内容始终通过引用。这很好,除非调用上下文不希望你(函数)修改它作为输入提供的变量。
Python 的解决方案是 1) 期望函数编写者正确记录可变输入的输入、输出和副作用,以及 2) 为调用上下文提供传递不可变对象的选项,如果他们想确保这些对象不会被更改。
因此,如果你有一个列表,并且你不希望你调用的某个函数从中添加或减去内容,请改为以元组的形式传递信息。任何函数都无法向元组添加或减去任何内容,但是如果这些元素是可变的,它们可能能够更改元组的元素。传递一个冻结集,而不是一个集合。没有不可变的 dict 类型,但您可以通过传递副本或将其转换为冻结的元组集来绕过它。字符串、整数、浮点数和复数都是不可变的。请注意,嵌入在不可变容器中的可变对象仍然可以更改。如果这是不希望的,请确保它们是不可变的。或者,如果你是偏执狂,你可以对一个对象调用 copy.deepcopy() 来制作一个完全独立的副本(递归方式)以传递到函数中。此深层拷贝的任何嵌套级别的任何更改都不会影响原始对象。
在编写函数时,应该从文档(最好是 docstring)或代码本身中清楚地了解返回值和对可变对象的副作用是什么。在编写函数时,使用文档字符串来捕获这一点是最佳做法。
调用函数时,应根据特定情况的需要防御性地使用不可变类型(或深度复制,如果需要)。
评论
my_set.my_lovely_method(my_graph)