Python은 저의 첫 번째 동적 언어입니다. 최근에 잘못된 수의 인수를 잘못 제공하는 함수 호출을 코딩했습니다. 함수가 호출되었을 때 예외로 인해 실패했습니다. 동적 언어에서도 소스 파일을 구문 분석 할 때 이러한 종류의 오류가 감지 될 수있을 것으로 예상했습니다.
동일한 변수가 다른 시간에 모든 유형의 값을 포함 할 수 있기 때문에 함수가 호출 될 때까지 실제 인수 의 유형 을 알 수 없다는 것을 이해합니다 . 그러나 인수 의 수 는 소스 파일이 구문 분석되는 즉시 알려집니다. 프로그램이 실행되는 동안에는 변경되지 않습니다.
그래서 이것은 철학적 인 질문이 아닙니다.
이것을 Stack Overflow의 범위로 유지하기 위해 다음과 같은 질문을 표현하겠습니다. 코드가 실제로 실행될 때까지 함수 호출에서 인수 수 확인을 지연해야하는 Python이 제공하는 기능이 있습니까?
답변
파이썬은 어떤 객체를 호출하게 될지 미리 알 수 없습니다. 왜냐하면 동적이기 때문에 함수 객체를 교체 할 수 있기 때문 입니다. 언제든지. 그리고 이러한 각 객체는 서로 다른 수의 인수를 가질 수 있습니다.
다음은 극단적 인 예입니다.
import random
def foo(): pass
def bar(arg1): pass
def baz(arg1, arg2): pass
the_function = random.choice([foo, bar, baz])
print(the_function())
위의 코드는 예외가 발생할 확률이 3 분의 2입니다. 하지만 파이썬은 그것이 사실인지 아닌지 선험적을 알 수 없습니다!
그리고 동적 모듈 가져 오기, 동적 함수 생성, 기타 호출 가능한 개체 ( __call__
메서드가있는 모든 개체를 호출 할 수 있음) 또는 모든 인수 ( *args
및 **kwargs
)를 시작하지 않았습니다 .
그러나이를 더욱 명확하게하기 위해 질문에 다음과 같이 진술합니다.
프로그램이 실행되는 동안에는 변경되지 않습니다.
파이썬이 아니라 모듈이로드되면 함수 객체를 포함하여 모듈 네임 스페이스의 모든 객체를 삭제, 추가 또는 교체 할 수 있습니다.
답변
전달되는 인수의 수는 알려져 있지만 실제로 호출되는 함수는 알려져 있지 않습니다. 이 예를 참조하십시오.
def foo():
print("I take no arguments.")
def bar():
print("I call foo")
foo()
이것은 분명해 보일 수 있지만 “fubar.py”라는 파일에 넣어 보겠습니다. 이제 대화 형 Python 세션에서 다음을 수행합니다.
>>> import fubar
>>> fubar.foo()
I take no arguments.
>>> fubar.bar()
I call foo
I take no arguments.
그것은 분명했습니다. 이제 재미있는 부분입니다. 0이 아닌 양의 인수가 필요한 함수를 정의합니다.
>>> def notfoo(a):
... print("I take arguments!")
...
이제 우리는 원숭이 패치 라고하는 것을 합니다. 실제로 모듈 에서 함수 를 대체 할 수 있습니다 .foo
fubar
>>> fubar.foo = notfoo
이제 우리가를 호출 할 때 bar
, a TypeError
가 발생합니다. foo
이제 이름 은 이전에 알려진 원래 함수 대신 위에서 정의한 함수를 참조합니다 foo
.
>>> fubar.bar()
I call foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/horazont/tmp/fubar.py", line 6, in bar
foo()
TypeError: notfoo() missing 1 required positional argument: 'a'
따라서 이와 같은 상황에서도 호출 된 함수 foo
가 인수를 취하지 않는다는 것이 매우 명백해 보일 수 있지만 , Python foo
은 해당 소스 행을 실행할 때 실제로 호출되는 함수 임을 알 수만 있습니다 .
이것은 Python의 속성으로 강력하게 만들지 만 속도가 느려집니다. 사실, 성능 향상을 위해 모듈을 읽기 전용으로 만드는 것은 얼마 전에 python-ideas 메일 링리스트 에서 논의 되었지만 실제 지원을 얻지 못했습니다.