Forced naming of parameters in Python

后端 未结 11 1274
日久生厌
日久生厌 2020-11-27 12:15

In Python you may have a function definition:

def info(object, spacing=10, collapse=1)

which could be called in any of the following ways:<

11条回答
  •  失恋的感觉
    2020-11-27 13:12

    True, most programming languages make parameter order part of the function call contract, but this doesn't need to be so. Why would it? My understanding of the question is, then, if Python is any different to other programming languages in this respect. In addition to other good answers for Python 2, please consider the following:

    __named_only_start = object()
    
    def info(param1,param2,param3,_p=__named_only_start,spacing=10,collapse=1):
        if _p is not __named_only_start:
            raise TypeError("info() takes at most 3 positional arguments")
        return str(param1+param2+param3) +"-"+ str(spacing) +"-"+ str(collapse)
    

    The only way a caller would be able to provide arguments spacing and collapse positionally (without an exception) would be:

    info(arg1, arg2, arg3, module.__named_only_start, 11, 2)
    

    The convention of not using private elements belonging to other modules already is very basic in Python. As with Python itself, this convention for parameters would only be semi-enforced.

    Otherwise, calls would need to be of the form:

    info(arg1, arg2, arg3, spacing=11, collapse=2)
    

    A call

    info(arg1, arg2, arg3, 11, 2)
    

    would assign value 11 to parameter _p and an exception risen by the function's first instruction.

    Characteristics:

    • Parameters before _p=__named_only_start are admitted positionally (or by name).
    • Parameters after _p=__named_only_start must be provided by name only (unless knowledge about the special sentinel object __named_only_start is obtained and used).

    Pros:

    • Parameters are explicit in number and meaning (the later if good names are also chosen, of course).
    • If the sentinel is specified as first parameter, then all arguments need to be specified by name.
    • When calling the function, it's possible to switch to positional mode by using the sentinel object __named_only_start in the corresponding position.
    • A better performance than other alternatives can be anticipated.

    Cons:

    • Checking occurs during run-time, not compile-time.
    • Use of an extra parameter (though not argument) and an additional check. Small performance degradation respect to regular functions.
    • Functionality is a hack without direct support by the language (see note below).
    • When calling the function, it's possible to switch to positional mode by using the sentinel object __named_only_start in the right position. Yes, this can also be seen as a pro.

    Please do keep in mind that this answer is only valid for Python 2. Python 3 implements the similar, but very elegant, language-supported mechanism described in other answers.

    I've found that when I open my mind and think about it, no question or other's decision seems stupid, dumb, or just silly. Quite on the contrary: I typically learn a lot.

提交回复
热议问题