Để trả lời câu hỏi về cách sử dụng tốt cho các giá trị đối số mặc định có thể thay đổi, tôi đưa ra ví dụ sau:
Mặc định có thể thay đổi có thể hữu ích cho việc lập trình các lệnh dễ sử dụng, có thể nhập do bạn tạo ra. Phương thức mặc định có thể thay đổi có thể có các biến tĩnh, riêng tư trong một hàm mà bạn có thể khởi tạo trong lần gọi đầu tiên (rất giống với một lớp) nhưng không cần phải sử dụng đến toàn cầu, không cần phải sử dụng trình bao bọc và không cần phải khởi tạo đối tượng lớp đã được nhập. Nó theo cách riêng của nó thanh lịch, như tôi hy vọng bạn sẽ đồng ý.
Hãy xem xét hai ví dụ sau:
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()
Nếu bạn chạy mã này, bạn sẽ thấy rằng hàm dittle () nội bộ hóa trong cuộc gọi đầu tiên chứ không phải trong các cuộc gọi bổ sung, nó sử dụng bộ đệm tĩnh riêng (mặc định có thể thay đổi) để lưu trữ tĩnh nội bộ giữa các cuộc gọi, từ chối các nỗ lực chiếm đoạt lưu trữ tĩnh, có khả năng chống lại đầu vào độc hại và có thể hoạt động dựa trên các điều kiện động (ở đây là số lần hàm đã được gọi.)
Chìa khóa để sử dụng giá trị mặc định có thể thay đổi không phải làm bất cứ điều gì sẽ gán lại biến trong bộ nhớ, mà là luôn thay đổi biến tại chỗ.
Để thực sự thấy sức mạnh tiềm tàng và tính hữu ích của kỹ thuật này, hãy lưu chương trình đầu tiên này vào thư mục hiện tại của bạn với tên "DITTLE.py", sau đó chạy chương trình tiếp theo. Nó nhập và sử dụng lệnh dittle () mới của chúng tôi mà không yêu cầu bất kỳ bước nào để ghi nhớ hoặc lập trình vòng lặp để nhảy qua.
Đây là ví dụ thứ hai của chúng tôi. Biên dịch và chạy chương trình này như một chương trình mới.
from DITTLE import dittle
print("\n We have emulated a new python command with 'dittle()'.\n")
dittle()
dittle()
dittle()
dittle()
dittle()
Bây giờ không phải là bóng bẩy và sạch sẽ nhất có thể? Các giá trị mặc định có thể thay đổi này thực sự có ích.
========================
Sau khi suy nghĩ về câu trả lời của mình một lúc, tôi không chắc rằng mình đã tạo ra sự khác biệt giữa việc sử dụng phương pháp mặc định có thể thay đổi và cách thông thường để hoàn thành cùng một điều rõ ràng.
Cách thông thường là sử dụng một hàm có thể nhập để bao bọc một đối tượng Lớp (và sử dụng một toàn cục). Vì vậy, để so sánh, đây là một phương thức dựa trên Lớp cố gắng thực hiện những điều tương tự như phương thức mặc định có thể thay đổi.
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()
Lưu chương trình dựa trên Lớp này trong thư mục hiện tại của bạn với tên DITTLE.py, sau đó chạy mã sau (mã này giống như trước đó.)
from DITTLE import dittle
dittle()
dittle()
dittle()
dittle()
dittle()
Bằng cách so sánh hai phương pháp, lợi ích của việc sử dụng mặc định có thể thay đổi trong một hàm sẽ rõ ràng hơn. Phương thức mặc định có thể thay đổi không cần hình cầu, không thể đặt trực tiếp các biến bên trong. Và trong khi phương thức có thể thay đổi chấp nhận một đối số đã được thông qua cho một chu trình đơn lẻ sau đó loại bỏ nó, phương thức Lớp đã bị thay đổi vĩnh viễn vì biến bên trong của nó được tiếp xúc trực tiếp với bên ngoài. Đối với phương pháp nào dễ dàng hơn để lập trình? Tôi nghĩ rằng điều đó phụ thuộc vào mức độ thoải mái của bạn với các phương pháp và mức độ phức tạp của mục tiêu của bạn.