2010-02-22 47 views
8

tôi nhận thấy như sau:giá trị mặc định trong một hàm trong Python

class c: 
    def __init__(self, data=[]): 
    self._data=data 
a=c() 
b=c() 
a._data.append(1) 
print b._data 
[1] 

Đây có phải là hành vi có đúng không?

+2

Vui lòng đọc tài liệu đánh dấu để xem cách định dạng mã chính xác. Nó nằm ở bên phải của trang. Vui lòng cập nhật câu hỏi của bạn để thụt lề mã 4 dấu cách. –

+0

Liên quan: http://stackoverflow.com/questions/1011431/python-things-one-must-avoid, http://stackoverflow.com/questions/1534407/python-object-intialization-bug-or-am-i -misunderstanding-how-objects-work, http://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time-in-python –

Trả lời

11

Vâng, đó là hành vi đúng.

Tuy nhiên, từ câu hỏi của bạn, có vẻ như đó không phải là những gì bạn mong đợi.

Nếu bạn muốn nó phù hợp với mong đợi của bạn, hãy lưu ý những điều sau đây:

Quy tắc 1. Không sử dụng các đối tượng có thể thay đổi làm giá trị mặc định.

def anyFunction(arg=[]): 

Sẽ không tạo đối tượng danh sách mới. Đối tượng danh sách mặc định cho arg sẽ được chia sẻ khắp nơi.

Tương tự

def anyFunction(arg={}): 

sẽ không tạo ra một đối tượng dict tươi. Dict mặc định này sẽ được chia sẻ.

class MyClass(object): 
    def __init__(self, arg= None): 
     self.myList= [] if arg is None else arg 

Đó là cách phổ biến để cung cấp giá trị đối số mặc định là đối tượng danh sách trống, trống.

+3

'Sẽ không bao giờ hoạt động.' là một chút khắc nghiệt. 'Sẽ không cung cấp cho bạn một đối tượng có thể thay đổi trống mới trên mỗi cuộc gọi', có vẻ cân bằng hơn một chút. Nếu bạn biết điều này xảy ra, bạn có thể thực sự muốn sử dụng hành vi này. – MattH

+0

@MattH: Việc sử dụng lại cùng một đối tượng có thể thay đổi được thông qua một giá trị mặc định rất kỳ quặc đến nỗi nó bất chấp việc tìm kiếm một trường hợp sử dụng hợp lý. Đó là một giá trị * mặc định *, vì vậy nó có thể (hoặc có thể không) được sử dụng như vậy tùy thuộc vào việc sử dụng giao diện của khách hàng. Nó sẽ rất khó để chẩn đoán vấn đề với điều này mà tôi đứng bởi công thức ban đầu của tôi. Đặc biệt đối với n00bz. –

+0

Bạn nên thêm một ví dụ về cách giải quyết vấn đề này. Nếu không câu trả lời là tốt và chính xác. – ironfroggy

1

Luôn chắc chức năng như thế này thì:

def __init__ (self, data = None): 
    if data is None: 
     data = [] 

    self._data = data 

Hoặc bạn cũng có thể sử dụng data = data or [], nhưng có thể ngăn chặn người dùng từ đi qua trống thông số ('', 0, False v.v.).

+0

Tất nhiên bạn cũng có thể làm 'nếu không dữ liệu: dữ liệu = []'. – voyager

+0

ví dụ của bạn 'dữ liệu = dữ liệu hoặc [] 'hoạt động tốt cho các danh sách trống được chuyển. Bạn sẽ nói rằng 'dữ liệu' sẽ là' [] hoặc [] 'vì vậy nó sẽ xem xét cái đầu tiên và thấy rằng nó đánh giá là" false ", sau đó nó sẽ lấy giá trị khác. – tgray

+1

Tôi biết, quan điểm của tôi là khi bạn vượt qua 'False' chẳng hạn,' [] 'sẽ được sử dụng làm giá trị, mặc dù bạn đã vượt qua' False'. – poke

Các vấn đề liên quan