2009-12-15 23 views
12

Mã số setdefault của Python cho phép bạn lấy giá trị từ một từ điển, nhưng nếu khóa không tồn tại, thì bạn chỉ định dựa trên tham số default. Sau đó, bạn lấy bất cứ điều gì là chìa khóa trong từ điển.Trong python, có một setdefault() tương đương để nhận các thuộc tính đối tượng không?

Nếu không thao tác đối tượng __dict__ Có chức năng tương tự cho đối tượng không?

ví dụ:
Tôi có một đối tượng foo có thể có hoặc không có thuộc tính bar. Làm thế nào tôi có thể làm một cái gì đó như:

result = setdefaultattr(foo,'bar','bah') 

Trả lời

6

Python không có một xây dựng trong, nhưng bạn có thể định nghĩa của riêng bạn:

def setdefaultattr(obj, name, value): 
    if not hasattr(obj, name): 
     setattr(obj, name, value) 
    return getattr(obj, name) 
+0

Điều gì về 'def setdefaultattr (o, n, v): trả về setdefault (o .__ dict__, n, v)'? Điều đó sẽ không làm việc trên các lớp học với khe mặc dù. –

1
vars(obj).setdefault(name, value) 
+0

Vì vậy, vars() chỉ trả về obj .__ dict__? –

+0

(Tôi thích cú pháp var() đến obj .__ dict__) –

+1

@Ross chắc chắn. xem 'help (vars)' –

19

Lưu ý rằng câu trả lời chấp nhận hiện nay sẽ, nếu thuộc tính không tồn tại, đã gọi hasattr(), setattr() và getattr(). Điều này sẽ là cần thiết chỉ khi OP đã làm một cái gì đó như setattr trọng và/hoặc getattr - trong trường hợp đó OP không phải là người yêu cầu vô tội chúng tôi đã đưa anh ta cho. Nếu không gọi tất cả 3 hàm là tổng; cuộc gọi setattr() phải được theo sau bởi return value để không rơi qua số return getattr(....)

Theo số docs, hasattr() được thực hiện bằng cách gọi getattr() và ngoại lệ bắt buộc. Mã sau có thể nhanh hơn khi thuộc tính đã tồn tại:

def setdefaultattr(obj, name, value): 
    try: 
     return getattr(obj, name) 
    except AttributeError: 
     setattr(obj, name, value) 
    return value 
+1

+1 cho EAFP (ngoại lệ bắt buộc) – tzot

+0

Tại sao điều này không hoạt động nếu đối tượng có một 'setattr' và/hoặc' getattr' bị ghi đè? – martineau

+0

phương pháp vars (obj) nhanh hơn một chút so với thử nghiệm của tôi (khoảng 5%) – sbaechler

0

Không làm điều này.

Vui lòng.

Sử dụng __init__ để cung cấp giá trị mặc định. Xin vui lòng. Đó là cách Pythonic.

class Foo(object): 
    def __init__(self): 
     self.bar = 'bah' 

Đây là cách tiếp cận thông thường, tiêu chuẩn, điển hình. Không có lý do thuyết phục để làm khác.

+1

Bạn nói đúng. Xấu hổ với tôi :-) Tôi chỉ nên sửa chữa hàm __init__. –

+0

@Ross Rogers: Làm ơn. –

+0

Có thể rất có lý do để làm những gì được yêu cầu, ví dụ: lưu trữ tạm thời các kết quả trong thuộc tính mà bạn chỉ cần khi thuộc tính thực sự được đọc. Bên cạnh đó, những gì bạn đang làm trong ví dụ của bạn tốt hơn nên là một thanh biến lớp đơn giản. Những gì bạn đang làm ist chỉ bloating mỗi đối tượng duy nhất mà không có lý do. – Michael

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