简体   繁体   English

区分只读 function 输入参数和可变输入参数的 Pythonic 方法

[英]Pythonic way to distinguish read-only function input parameters from mutable ones

Python doesn't seem to have a valid const qualifier per How do I create a constant in Python? Python 似乎没有有效的const限定符如何在 Python 中创建常量? What would be the most "pythonic" way for differentiating read-only / mutable function parameters?区分只读/可变 function 参数的最“pythonic”方式是什么? Should I just point it out in the comments?我应该在评论中指出吗?

# my_graph is READ-ONLY
# my_set is added items with property X ...
def my_lovely_function(my_graph,my_set):

In C and several other languages, typically real outputs are communicated via inputs that are passed by pointers or by reference.在 C 和其他几种语言中,通常实际输出是通过通过指针或引用传递的输入进行通信的。 The reason for this is that the return value mechanism in many of these paradigms has been hijacked for error handling purposes ie return value is a success/error code while useful outputs are populated in an input/pointer reference.这样做的原因是许多这些范例中的返回值机制已被劫持用于错误处理目的,即返回值是成功/错误代码,而有用的输出填充在输入/指针引用中。 This has led for the need to denote some inputs as being untouchable (consts) and others as being touchable to prevent confusion in using the function.这导致需要将某些输入表示为不可触摸(常量),而将其他输入表示为可触摸,以防止在使用 function 时出现混淆。

Python typically doesn't want you to do things that way. Python 通常不希望你那样做。 It wants you to use Exceptions and exception handling for error handling and to use return statements for actual outputs.它希望您使用异常和异常处理来处理错误,并使用 return 语句来处理实际输出。 This is cleaner and more in line with the original idea of return values before they were highjacked by error handling.这更清晰,更符合返回值在被错误处理劫持之前的原始想法。

In some cases, it is still more convenient to use a mutable input to transfer data out.在某些情况下,使用可变输入将数据传出更为方便。 Everything in python is always by reference. python 中的所有内容始终通过引用。 This is fine except if the calling context doesn't want you, the function, to modify the variable it provided as an input.这很好,除非调用上下文不希望您 function 修改它作为输入提供的变量。

Python's solution is to 1) expect the function writer to properly document inputs, outputs, and side-effects on mutable inputs, and 2) provide the calling context the option of passing in immutable objects if they want to ensure those objects will not be changed. Python 的解决方案是 1) 期望 function 编写器正确记录输入、输出和对可变输入的副作用,以及 2) 为调用上下文提供传递不可变对象的选项,如果他们想确保这些对象不会被更改.

So if you have a list and you don't want some function you call to add or subtract things from it, pass in the information as a tuple instead.因此,如果您有一个列表并且您不想调用 function 来从中添加或减去内容,请将信息作为元组传递。 No function will be able to add or subtract anything to your tuple, however they might be able to change elements of the tuple if those are mutable.没有 function 将能够向您的元组添加或减去任何内容,但是如果这些元素是可变的,他们可能能够更改元组的元素。 Instead of a set, pass a frozenset.传递一个 frozenset 而不是一个集合。 There is no immutable dict type, but you can get around that by passing a copy or translating it to a frozenset of tuples.没有不可变的 dict 类型,但您可以通过传递副本或将其转换为冻结的元组集来解决这个问题。 Strings, ints, floats, and complex numbers are all immutable.字符串、整数、浮点数和复数都是不可变的。 Note that mutable objects embedded in immutable containers can still be changed.请注意,嵌入在不可变容器中的可变对象仍然可以更改。 If this is undesired, then make sure they are immutable.如果这是不需要的,那么请确保它们是不可变的。 Alternatively, if you are paranoid, you can call copy.deepcopy() on an object to make a totally independent copy (recursively) to pass into the function. Any changes at any nested level of this deep copy will not affect the original object.或者,如果您偏执,您可以在 object 上调用 copy.deepcopy() 以制作完全独立的副本(递归)以传递到 function。此深层副本的任何嵌套级别的任何更改都不会影响原始 object。

When writing a function, it should be clear from the documentation (preferably docstring) or the code itself what the return values and side effects on mutable objects are.在编写 function 时,应该从文档(最好是文档字符串)或代码本身清楚可变对象的返回值和副作用是什么。 Using docstrings to capture this when writing a function is best practice.在编写 function 时使用文档字符串来捕获此内容是最佳实践。

When calling a function, you should defensively make use of immutable types (or deep copying if need be) as needed for your specific circumstances.拨打 function 时,您应该根据具体情况使用不可变类型(或在需要时使用深度复制)作为防御措施。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM