IT TIP

항상 키워드 인수를 사용하지 않는 이유가 있습니까?

itqueen 2020. 12. 15. 20:38
반응형

항상 키워드 인수를 사용하지 않는 이유가 있습니까?


파이썬에 뛰어 들기 전에 저는 Objective-C / Cocoa 책으로 시작했습니다. 내가 상기 한 바와 같이, 대부분의 함수는 명시 적으로 명시하기 위해 키워드 인자가 필요했습니다. 최근까지 나는 이것에 대해 모두 잊고 파이썬에서 위치 인수를 사용했습니다. 그러나 최근에 부적절한 위치로 인해 발생하는 몇 가지 버그를 만났습니다.

키워드가 아닌 인수를 특별히 요구하는 상황이 아니라면 일반적으로 말하면 키워드 인수를 사용하지 않는 좋은 이유가 있습니까? 단순한 기능에도 항상 사용하는 것이 나쁜 스타일로 간주됩니까?

대부분의 50 줄 프로그램이 정기적으로 500 줄 이상으로 확장되는 것처럼 느껴집니다. 항상 키워드 인수를 사용하는 데 익숙해지면 코드가 커짐에 따라 더 쉽게 읽고 유지 관리 할 수 ​​있습니다. 그렇지 않은 이유는 무엇입니까?

최신 정보:

내가 얻는 일반적인 인상은 일반적으로 매우 간단한 주장에 사용해서는 안되지만 좋은 스타일과 일치한다는 많은 좋은 주장과 함께 스타일 선호라는 것입니다. 수락하기 전에 명확히하고 싶습니다.이 방법에서 발생하는 특정 비스타 일 문제 (예 : 심각한 성능 저하)가 있습니까?


코드의 명확성과 가독성을 제외하고는 키워드 인수를 사용하지 않을 이유가 없습니다. 키워드 사용 여부는 키워드가 코드를 읽을 때 유용한 정보를 추가하는지 여부에 따라 선택해야합니다.

나는 다음 일반 규칙을 따릅니다.

  1. 함수 이름에서 인수의 함수 (이름)를 추론하기 어렵다면 키워드로 전달하십시오 (예 : text.splitlines(True)코드에 포함 하고 싶지 않음 ).
  2. 인수의 순서를 추론하기 어려운 경우, 예를 들어 인수가 너무 많거나 독립적 인 선택적 인수가있는 경우-키워드로 전달하십시오 (예 : funkyplot(x, y, None, None, None, None, None, None, 'red')특별히보기 좋지 않음).
  3. 인수의 목적이 분명한 경우 처음 몇 개의 인수를 키워드로 전달하지 마십시오. 당신은 볼 sin(2*pi)보다 낫다 sin(value=2*pi)동일 마찬가지입니다 plot(x, y, z).

대부분의 경우 안정된 필수 인수는 위치이고 선택적 인수는 키워드입니다.

또한 모든 구현에서 키워드 인수가 약간 느리기 때문에 성능에 차이가있을 수 있습니다. 그러나 이것이 일반적으로 조기 최적화이고 그 결과가 중요하지 않다는 점을 고려하면 결정에 중요하지 않다고 생각합니다. .

업데이트 : 스타일리스트가 아닌 문제

키워드 인수는 위치 인수가 할 수있는 모든 작업을 수행 할 수 있으며 새 API를 정의하는 경우 가능한 성능 문제 외에 기술적 단점이 없습니다. 그러나 코드를 기존 요소와 결합하는 경우 문제가 거의 없을 수 있습니다.

다음을 고려하세요:

  • 함수가 키워드 인수를 받도록 만들면 인터페이스의 일부가됩니다. 서명은 비슷하지만 동일한 인수에 대해 다른 키워드를 사용하는 다른 함수로 함수를 바꿀 수 없습니다.
  • 함수가 위치 인수를 취한다고 가정하는 데코레이터 또는 함수에 다른 유틸리티를 사용할 수 있습니다. 언 바운드 메서드는 위치로 읽은 후 항상 첫 번째 인수를 위치로 전달하므로 정의에 cls.method(self=cls_instance)인수가 있어도 작동하지 않기 때문에 이러한 유틸리티의 예입니다 self.

API를 잘 설계하고 키워드 인수의 사용을 문서화하는 경우, 특히 이미 존재하는 것과 상호 교환 할 수있는 것을 설계하지 않는 경우 이들 중 어느 것도 실제 문제가되지 않습니다.


함수 호출의 가독성을 높이는 것이 고려 사항이라면 단순히 함수를 정상으로 선언하지 않는 이유는 무엇입니까?

def test(x, y):
    print "x:", x
    print "y:", y

다음과 같이 명시 적으로 이름을 선언하여 함수를 호출하기 만하면됩니다.

test(y=4, x=1)

분명히 출력을 제공합니다.

x: 1
y: 4

아니면이 운동은 무의미 할 것입니다.

이렇게하면 인수가 선택 사항이고 기본값이 필요하지 않습니다 (원하는 경우가 아니면 키워드 인수로 진행하십시오! :). 순서에 의해 제한되지 않는 명명 된 인수의 모든 다양성과 향상된 가독성을 제공합니다.


글쎄요, 제가 그렇게하지 않는 데에는 몇 가지 이유가 있습니다.

모든 인수가 키워드 인수 인 경우 코드에 노이즈가 증가하고 어떤 인수가 필요하고 어떤 인수가 옵션인지에 대한 명확성이 제거 될 수 있습니다.

또한 당신의 코드를 사용해야한다면 당신을 죽이고 싶을지도 모릅니다 !! (농담입니다), 매번 모든 매개 변수의 이름을 입력해야합니다.


UNIX 프로그램에서 "옵션"에 대한 아주 좋은 설명을 읽은 기억이납니다. "옵션은 선택 사항입니다. 프로그램은 옵션 없이도 실행할 수 있어야합니다."

파이썬의 키워드 인자 에도 동일한 원칙이 적용될 수 있습니다 . 이러한 종류의 인수는 사용자가 함수 호출을 "사용자 지정"할 수 있도록해야하지만 암시 적 키워드-값 인수 쌍없이 함수를 호출 할 수 있어야합니다.


다른 주장을 제공하기 위해 명명 된 매개 변수가 가독성을 향상시킬 수있는 경우가 있다고 생각합니다. 예를 들어 시스템에서 사용자를 생성하는 함수를 상상해보십시오.

create_user("George", "Martin", "g.m@example.com", "payments@example.com", "1", "Radius Circle")

이 정의에서 이러한 값이 무엇을 의미 할 수 있는지는 전혀 명확하지 않지만 모두 필수 항목이지만 명명 된 매개 변수를 사용하면 항상 분명합니다.

create_user(
    first_name="George",
    last_name="Martin",
    contact_email="g.m@example.com",
    billing_email="payments@example.com",
    street_number="1",
    street_name="Radius Circle")

때로는 단순하기 때문에 단순해야합니다.

모든 함수 호출에 항상 키워드 인수를 사용하도록 강요하면 곧 코드를 읽을 수 없게됩니다.


When Python's built-in compile() and __import__() functions gain keyword argument support, the same argument was made in favor of clarity. There appears to be no significant performance hit, if any.

Now, if you make your functions only accept keyword arguments (as opposed to passing the positional parameters using keywords when calling them, which is allowed), then yes, it'd be annoying.


I don't see the purpose of using keyword arguments when the meaning of the arguments is obvious


Keyword args are good when you have long parameter lists with no well defined order (that you can't easily come up with a clear scheme to remember); however there are many situations where using them is overkill or makes the program less clear.

First, sometimes is much easier to remember the order of keywords than the names of keyword arguments, and specifying the names of arguments could make it less clear. Take randint from scipy.random with the following docstring:

randint(low, high=None, size=None)    
Return random integers x such that low <= x < high.
If high is None, then 0 <= x < low.

When wanting to generate a random int from [0,10) its clearer to write randint(10) than randint(low=10) in my view. If you need to generate an array with 100 numbers in [0,10) you can probably remember the argument order and write randint(0, 10, 100). However, you may not remember the variable names (e.g., is the first parameter low, lower, start, min, minimum) and once you have to look up the parameter names, you might as well not use them (as you just looked up the proper order).

Also consider variadic functions (ones with variable number of parameters that are anonymous themselves). E.g., you may want to write something like:

def square_sum(*params):
    sq_sum = 0
    for p in params:
        sq_sum += p*p
    return sq_sum

that can be applied a bunch of bare parameters (square_sum(1,2,3,4,5) # gives 55 ). Sure you could have written the function to take an named keyword iterable def square_sum(params): and called it like square_sum([1,2,3,4,5]) but that may be less intuitive, especially when there's no potential confusion about the argument name or its contents.


One downside I could see is that you'd have to think of a sensible default value for everything, and in many cases there might not be any sensible default value (including None). Then you would feel obliged to write a whole lot of error handling code for the cases where a kwarg that logically should be a positional arg was left unspecified.

Imagine writing stuff like this every time..

def logarithm(x=None):
    if x is None:
        raise TypeError("You can't do log(None), sorry!")

A mistake I often do is that I forget that positional arguments have to be specified before any keyword arguments, when calling a function. If testing is a function, then:

testing(arg = 20, 56)

gives a SyntaxError message; something like:

SyntaxError: non-keyword arg after keyword arg

It is easy to fix of course, it's just annoying. So in the case of few - lines programs as the ones you mention, I would probably just go with positional arguments after giving nice, descriptive names to the parameters of the function. I don't know if what I mention is that big of a problem though.

ReferenceURL : https://stackoverflow.com/questions/7041752/any-reason-not-to-always-use-keyword-arguments

반응형