Değişken varsayılan argüman değerlerinin iyi kullanımları sorusuna yanıt olarak, aşağıdaki örneği sunuyorum:
Değiştirilebilir bir varsayılan, kendi oluşturduğunuz, kullanımı kolay, içe aktarılabilir komutları programlamak için yararlı olabilir. Değişebilir varsayılan yöntem, bir işlevde ilk çağrıda (bir sınıfa çok benzer), ancak globallere başvurmak zorunda kalmadan, bir sarmalayıcı kullanmak zorunda kalmadan ve bir içe aktarılan sınıf nesnesi. Kendi yolunda zarif, umarım kabul edersiniz.
Şu iki örneği düşünün:
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()
Bu kodu çalıştırırsanız, dittle () işlevinin ilk çağrıda içselleştirildiğini, ancak ek çağrılarda olmadığını göreceksiniz, çağrılar arasında dahili statik depolama için özel bir statik önbellek (değiştirilebilir varsayılan) kullanır, kaçırma girişimlerini reddeder. statik depolama, kötü amaçlı girdilere karşı dayanıklıdır ve dinamik koşullara göre hareket edebilir (burada işlevin kaç kez çağrıldığına göre).
Değişken varsayılanları kullanmanın anahtarı, değişkeni bellekte yeniden atayacak hiçbir şey yapmamak, değişkeni her zaman yerinde değiştirmektir.
Bu tekniğin potansiyel gücünü ve kullanışlılığını gerçekten görmek için, bu ilk programı "DITTLE.py" adı altında mevcut dizininize kaydedin ve ardından sonraki programı çalıştırın. Yeni dittle () komutumuzu hatırlamak için herhangi bir adım gerektirmeden veya çemberleri atlamak için programlamadan alır ve kullanır.
İşte ikinci örneğimiz. Bunu yeni bir program olarak derleyin ve çalıştırın.
from DITTLE import dittle
print("\n We have emulated a new python command with 'dittle()'.\n")
dittle()
dittle()
dittle()
dittle()
dittle()
Şimdi bu olabildiğince kaygan ve temiz değil mi? Bu değiştirilebilir varsayılanlar gerçekten kullanışlı olabilir.
========================
Cevabımı bir süre düşündükten sonra, değiştirilebilir varsayılan yöntemi kullanmakla aynı şeyi başarmanın normal yolu arasındaki farkı net bir şekilde yaptığımdan emin değilim.
Normal yol, bir Class nesnesini saran (ve bir global kullanan) içe aktarılabilir bir işlev kullanmaktır. Karşılaştırma için, burada değiştirilebilir varsayılan yöntemle aynı şeyleri yapmaya çalışan Sınıf tabanlı bir yöntem.
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()
Bu Sınıf tabanlı programı mevcut dizininize DITTLE.py olarak kaydedin ve ardından aşağıdaki kodu çalıştırın (önceki ile aynıdır)
from DITTLE import dittle
dittle()
dittle()
dittle()
dittle()
dittle()
İki yöntemi karşılaştırarak, bir işlevde değiştirilebilir bir varsayılan kullanmanın avantajları daha net olmalıdır. Değiştirilebilir varsayılan yöntemin globale ihtiyacı yoktur, dahili değişkenleri doğrudan ayarlanamaz. Değişken yöntem, tek bir döngü için bilgili bir geçerliliği olan argümanı kabul edip omuzlarını silkerken, Sınıf yöntemi kalıcı olarak değiştirildi çünkü dahili değişkeni doğrudan dışarıya maruz kaldı. Hangi yöntemin programlanması daha kolaydır? Bunun, yöntemlerle rahatlığınıza ve hedeflerinizin karmaşıklığına bağlı olduğunu düşünüyorum.