2010-10-31 30 views
7

Groovy có một nhà điều hành tốt đẹp cho dereferencing an toàn, giúp tránh NullPointerExceptions:dereferencing an toàn bằng Python

variable?.method() 

Các method sẽ chỉ được gọi là, nếu không phải là variablenull.

Có cách nào để thực hiện tương tự trong Python không? Hay tôi phải viết if variable: variable.method()?

+1

@deamon: trước hết tôi không biết Groovy và tôi không muốn tranh luận về những gì tôi không biết nhưng tính năng này (sau khi tôi đọc về nó ngay bây giờ) dường như không hữu ích cho tôi (và tôi có thể là sai và hầu hết thời gian tôi) bởi vì ngay cả khi tôi làm một cái gì đó như thế này __variable.?method()__ có chắc chắn nếu biến là NULL nó không nâng cao một lỗi nhưng làm thế nào tôi biết rằng phương pháp này được gọi, bởi vì nó nhìn tôi như một lỗi im lặng (thực ra tôi không bao giờ cần một cái gì đó như thế này trước đây) và nếu tôi làm một cái gì đó như thế này __a = variable.?method()__ vì vậy sau khi tôi nên làm __if (a) __ vậy ..., tôi có bỏ lỡ điều gì đó không :) – mouad

+1

Tôi đồng ý với sự kỳ dị; Tôi không thấy điều này có thể hữu ích như thế nào. Nó trông giống như một cái gì đó bạn sẽ rắc trên mã của bạn để ẩn lỗi. – adw

+0

@ Johnson Johnson: bạn có thể cụ thể hơn không, tôi đã nói điều gì đó sai và nếu đó là về tiếng Anh của tôi thì điều đó có tệ không? nó không phải là ngôn ngữ đầu tiên của tôi :) – mouad

Trả lời

10
  1. Không, không có.

  2. Nhưng để kiểm tra None, bạn không viết if x:, bạn viết if x is None:. Đây là một khác biệt quan trọng - x đánh giá để False cho khá một vài giá trị mà là propably hoàn toàn hợp lệ (đặc biệt là 0 tương đương hầu hết các con số và các bộ sưu tập trống), trong khi x is Nonechỉ đánh giá để True nếu tham chiếu x điểm đến đối tượng singleton None .

  3. Từ kinh nghiệm cá nhân, nhà điều hành như vậy sẽ rất cần thiết. Có, None đôi khi được sử dụng để cho biết không có giá trị. Nhưng bằng cách nào đó - có thể vì mã thành ngữ trả về null objects trong đó hợp lý hoặc ném ngoại lệ để cho biết lỗi nghiêm trọng - tôi chỉ nhận được AttributeError: 'NoneType' object has no attribute '...' hai lần một tháng.

  4. Tôi cho rằng đây có thể là sự không hài lòng. null có hai nghĩa - "quên khởi tạo" và "không có dữ liệu". đầu tiên là lỗi và phải ném một ngoại lệ. Trường hợp thứ hai thường yêu cầu xử lý phức tạp hơn "chúng ta không gọi phương thức này". Khi tôi hỏi cơ sở dữ liệu/ORM cho số UserProfile, nó không có ở đó và tôi nhận được null thay vào đó ... tôi có muốn bỏ qua phần còn lại của phương thức không? Hoặc tôi thực sự muốn (khi trong "mã thư viện") ném một ngoại lệ approriate (vì vậy "người dùng (mã)" biết người dùng không có và có thể phản ứng ... hoặc bỏ qua nó) hoặc (khi tôi mã hóa một tính năng cụ thể) hiển thị thông báo hợp lý ("Người dùng đó không tồn tại, bạn không thể thêm nó vào danh sách bạn bè") cho người dùng?

3

Python không có thứ gì như vậy. Điều này là do không có con trỏ null bằng Python. Vâng, có giá trị đặc biệt None, thường được sử dụng trong các tình huống, nơi nó đại diện cho "không có giá trị". Nhưng đó chỉ là một quy ước. None là một giá trị/đối tượng giống như tất cả các đối tượng khác. Và vì không có null, nên không có toán tử nào để xử lý nó.

+1

Tôi đồng ý, nhưng 'None' về bản chất là giống nhau trong trường hợp này. Thay vì một 'NullPointerException' tôi sẽ nhận được một' AttributeError', nhưng tôi không thể gọi một phương thức trên 'None' sẽ có mặt trong đối tượng thông thường như danh sách. – deamon

+1

Vấn đề là, 'Không có' không phải là "bất thường". Nó là một đối tượng với một lớp thích hợp, có phương pháp, v.v.Không có gì trong ngôn ngữ mà sẽ làm cho nó đặc biệt trong bất kỳ cách nào (bên cạnh đó, nó đang được sử dụng để đại diện cho "không có gì thú vị ở đây" giá trị). Vì vậy, những gì sẽ giả định '? .' điều hành thử nghiệm cho? Đối với 'None' cụ thể? Còn các thư viện khác sử dụng các điểm đánh dấu khác (ví dụ: 'NOT_FOUND' trong PEAK) thì sao? – Dirk

+2

'None' là lựa chọn tuyệt vời để đánh dấu các đối số hàm tùy chọn và nhiều thứ khác, nhưng sử dụng nó (hoặc thứ gì đó như' NOT_FOUND') làm kết quả "không tìm thấy" hoặc giá trị trả về đặc biệt khác nên tránh. Sử dụng các ngoại lệ cho các loại điều kiện đặc biệt này tốt hơn vì nó có xu hướng đơn giản hóa mã bằng cách sử dụng các hàm đó (thay vì kiểm tra mọi giá trị trả về, bạn có thể có một mệnh đề ngoại trừ, hoặc chỉ để cho bong bóng ngoại lệ lên). – adw

3

Thành ngữ tôi đã xem và sử dụng là callable(func) and func(a, b, c) thay cho giá trị trả lại không được sử dụng). Tuy nhiên, nếu bạn đang cố gắng sử dụng giá trị trả lại, thành ngữ này sẽ mang lại False nếu chức năng không thể gọi được, có thể không phải là những gì bạn muốn. Trong trường hợp này, bạn có thể sử dụng toán tử bậc ba để cung cấp một giá trị mặc định. Ví dụ: nếu hàm sẽ trả về danh sách mà bạn sẽ lặp lại, bạn có thể sử dụng danh sách trống làm giá trị mặc định với func(a, b, c) if callable(func) else [].

2

Tôi đã sử dụng tính năng này trong Groovy, vì vậy tôi sẽ không lặp lại nghịch lý blub của các áp phích khác.

Trong Groovy một tuyên bố như thế này

if(possiblyNull?.value){ 
    ... 

Liệu này bằng Python

try: 
    testVar = possiblyNull.value 
except: 
    testVar = None 
if(testVar): 

Đó chắc chắn là một tính năng thú vị trong Groovy, và rất có ích trong việc loại bỏ tiếng ồn cú pháp. Có một vài bit khác của đường cú pháp, giống như toán tử Elvis hoặc *, nhưng chúng hy sinh tính dễ đọc như chi phí cho các ký hiệu sửa lỗi nhanh (nói cách khác, chúng không phải là Pythonic).

Hy vọng rằng sẽ giúp :-)

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