변경 가능한 기본 인수 값의 좋은 사용에 대한 질문에 대한 대답으로 다음 예제를 제공합니다.
변경 가능한 기본값은 사용하기 쉽고 직접 만든 가져 오기 가능한 명령을 프로그래밍하는 데 유용 할 수 있습니다. 변경 가능한 기본 메서드는 첫 번째 호출에서 초기화 할 수있는 (클래스와 매우 유사) 함수에 전용 정적 변수를 포함하지만 전역에 의존 할 필요가없고 래퍼를 사용하지 않고 인스턴스화 할 필요도 없습니다. 가져온 클래스 개체입니다. 당신이 동의하기를 바라는 것처럼 그것은 나름대로 우아합니다.
다음 두 가지 예를 고려하십시오.
def dittle(cache = []):
from time import sleep
if type(cache) != list or cache !=[] and (len(cache) == 2 and type(cache[1]) != int):
print(" User called dittle("+repr(cache)+").\n >> Warning: dittle() takes no arguments, so this call is ignored.\n")
return
if not cache:
print("\n cache =",cache)
print(" Initializing private mutable static cache. Runs only on First Call!")
cache.append("Hello World!")
cache.append(0)
print(" cache =",cache,end="\n\n")
cache[1]+=1
outstr = " dittle() called "+str(cache[1])+" times."
if cache[1] == 1:outstr=outstr.replace("s.",".")
print(outstr)
print(" Internal cache held string = '"+cache[0]+"'")
print()
if cache[1] == 3:
print(" Let's rest for a moment.")
sleep(2.0)
print(" Wheew! Ready to continue.\n")
sleep(1.0)
elif cache[1] == 4:
cache[0] = "It's Good to be Alive!"
if __name__ == "__main__":
for cnt in range(2):dittle()
print(" Attempting to pass an list to dittle()")
dittle([" BAD","Data"])
print(" Attempting to pass a non-list to dittle()")
dittle("hi")
print(" Calling dittle() normally..")
dittle()
print(" Attempting to set the private mutable value from the outside.")
dittle([" I am a Grieffer!\n (Notice this change will not stick!)",-7])
print(" Calling dittle() normally once again.")
dittle()
dittle()
이 코드를 실행하면 dittle () 함수가 첫 번째 호출에서 내부화되지만 추가 호출에서는 내부화되지 않으며 호출 사이의 내부 정적 저장소에 개인 정적 캐시 (변경 가능한 기본값)를 사용하고 하이재킹 시도를 거부합니다. 정적 저장소는 악의적 인 입력에 대해 탄력적이며 동적 조건 (여기서는 함수가 호출 된 횟수)에 따라 작동 할 수 있습니다.
가변 기본값을 사용하는 열쇠는 메모리에서 변수를 재 할당하는 작업을 수행하지 않고 항상 제자리에서 변수를 변경하는 것입니다.
이 기술의 잠재적 인 힘과 유용성을 확인하려면이 첫 번째 프로그램을 "DITTLE.py"라는 이름으로 현재 디렉토리에 저장 한 후 다음 프로그램을 실행하십시오. 기억하기위한 단계를 거치거나 점프 할 농구대를 프로그래밍하지 않고도 새로운 dittle () 명령을 가져 와서 사용합니다.
두 번째 예가 있습니다. 이것을 새 프로그램으로 컴파일하고 실행하십시오.
from DITTLE import dittle
print("\n We have emulated a new python command with 'dittle()'.\n")
dittle()
dittle()
dittle()
dittle()
dittle()
이제 가능한 한 매끄럽고 깨끗하지 않습니까? 이러한 변경 가능한 기본값은 실제로 유용 할 수 있습니다.
========================
잠시 내 대답을 생각해 본 후, 변경 가능한 기본 방법을 사용하는 것과 동일한 작업을 수행하는 일반적인 방법의 차이를 명확하게 만들지 못했습니다.
일반적인 방법은 Class 객체를 감싸고 전역을 사용하는 임포트 가능한 함수를 사용하는 것입니다. 따라서 비교를 위해 여기에는 변경 가능한 기본 메서드와 동일한 작업을 시도하는 클래스 기반 메서드가 있습니다.
from time import sleep
class dittle_class():
def __init__(self):
self.b = 0
self.a = " Hello World!"
print("\n Initializing Class Object. Executes on First Call only.")
print(" self.a = '"+str(self.a),"', self.b =",self.b,end="\n\n")
def report(self):
self.b = self.b + 1
if self.b == 1:
print(" Dittle() called",self.b,"time.")
else:
print(" Dittle() called",self.b,"times.")
if self.b == 5:
self.a = " It's Great to be alive!"
print(" Internal String =",self.a,end="\n\n")
if self.b ==3:
print(" Let's rest for a moment.")
sleep(2.0)
print(" Wheew! Ready to continue.\n")
sleep(1.0)
cl= dittle_class()
def dittle():
global cl
if type(cl.a) != str and type(cl.b) != int:
print(" Class exists but does not have valid format.")
cl.report()
if __name__ == "__main__":
print(" We have emulated a python command with our own 'dittle()' command.\n")
for cnt in range(2):dittle()
print(" Attempting to pass arguments to dittle()")
try:
dittle(["BAD","Data"])
except:
print(" This caused a fatal error that can't be caught in the function.\n")
print(" Calling dittle() normally..")
dittle()
print(" Attempting to set the Class variable from the outside.")
cl.a = " I'm a griefer. My damage sticks."
cl.b = -7
dittle()
dittle()
이 클래스 기반 프로그램을 현재 디렉토리에 DITTLE.py로 저장 한 후 다음 코드를 실행하십시오 (이전과 동일).
from DITTLE import dittle
dittle()
dittle()
dittle()
dittle()
dittle()
두 가지 방법을 비교하면 함수에서 가변 기본값을 사용하는 이점이 더 명확 해집니다. 변경 가능한 기본 메서드에는 전역이 필요하지 않으며 내부 변수를 직접 설정할 수 없습니다. 그리고 가변 메소드가 단일주기 동안 전달 된 인수를 받아 들인 다음이를 무시했지만, Class 메소드는 내부 변수가 외부에 직접 노출되기 때문에 영구적으로 변경되었습니다. 어떤 방법이 프로그래밍하기 더 쉬운가요? 나는 그것이 당신의 목표의 방법과 복잡성에 대한 당신의 편안함 수준에 달려 있다고 생각합니다.