Điều đó có nghĩa là gì nếu một đối tượng Python có thể đăng ký thành công hay không?


Câu trả lời:


357

Về cơ bản nó có nghĩa là đối tượng thực hiện __getitem__()phương thức. Nói cách khác, nó mô tả các đối tượng là "container", nghĩa là chúng chứa các đối tượng khác. Điều này bao gồm các chuỗi, danh sách, bộ dữ liệu và từ điển.


2
Làm thế nào đáng tin cậy sẽ: hasattr(SomeClassWithoutGetItem, '__getitem__')để xác định nếu một điều là có thể đăng ký?
jmunsch

2
Các [... ]lập chỉ mục cú pháp được gọi là một subscript , bởi vì nó tương đương với ký hiệu toán học mà sử dụng subscript thực tế; ví dụ: a[1]Python cho những gì các nhà toán học sẽ viết là a₁ . Vì vậy, "có thể đăng ký" có nghĩa là "có thể được đăng ký". Điều đó, theo thuật ngữ Python, có nghĩa là nó phải thực hiện __getitem__(), vì a[1]chỉ là đường cú pháp cho a.__getitem__(1).
Mark Reed

Lời kêu gọi đó hasattrsẽ hoạt động tốt, nhưng đó không phải là cách Pythonic để làm mọi việc; Thực hành Python khuyến khích gõ vịt . Có nghĩa là, nếu bạn có kế hoạch cố gắng tìm nạp một mục từ đối tượng của mình bằng cách sử dụng một mục con, hãy tiếp tục và thực hiện nó; nếu bạn nghĩ rằng nó có thể không hoạt động vì đối tượng không thể đăng ký được, hãy bọc nó trong một trykhối bằng một except TypeError.
Mark Reed

77

Ngoài đỉnh đầu của tôi, sau đây là những phần dựng sẵn duy nhất có thể đăng ký:

string:  "foobar"[3] == "b"
tuple:   (1,2,3,4)[3] == 4
list:    [1,2,3,4][3] == 4
dict:    {"a":1, "b":2, "c":3}["c"] == 3

Nhưng câu trả lời của mipadi là chính xác - bất kỳ lớp nào thực hiện __getitem__đều có thể đăng ký


17

Một đối tượng scriptable là một đối tượng ghi lại các hoạt động được thực hiện cho nó và nó có thể lưu trữ chúng dưới dạng một "script" có thể được phát lại.

Ví dụ: xem: Khung tập lệnh ứng dụng

Bây giờ, nếu Alistair không biết những gì anh ta hỏi và thực sự có nghĩa là các đối tượng "có thể đăng ký" (do người khác chỉnh sửa), thì (như mipadi cũng đã trả lời) đây là câu đúng:

Một đối tượng có thể đăng ký là bất kỳ đối tượng nào thực hiện __getitem__phương thức đặc biệt (liệt kê danh sách, từ điển).


2
Lưu ý rằng tôi đang trả lời câu hỏi ban đầu về các đối tượng "có thể viết được", chứ không phải "có thể đăng ký" như người khác chỉnh sửa, không phải Alistair. Tôi thực sự muốn Alistair bình luận.
tzot

Ah, một huy hiệu mới cho bộ sưu tập của tôi! :) Đùa thôi, rõ ràng. Điều duy nhất biện minh cho việc chỉnh sửa câu hỏi là Alistair đã chọn một câu trả lời; Tôi vẫn không chắc chắn nếu Alistair chắc chắn về việc lựa chọn.
tzot

17

Ý nghĩa của chỉ mục trong điện toán là: "một ký hiệu (được viết tắt là ký hiệu nhưng trong thực tế thường không được sử dụng) trong một chương trình, một mình hoặc với người khác, để chỉ định một trong các yếu tố của một mảng."

Bây giờ, trong ví dụ đơn giản được đưa ra bởi @ user2194711, chúng ta có thể thấy rằng phần tử nối thêm không thể là một phần của danh sách vì hai lý do: -

1) Chúng tôi không thực sự gọi phương thức nối thêm; bởi vì nó cần ()phải gọi nó

2) Lỗi chỉ ra rằng hàm hoặc phương thức không thể được đăng ký; có nghĩa là chúng không thể được lập chỉ mục như một danh sách hoặc chuỗi.

Bây giờ hãy xem điều này: -

>>> var = "myString"
>>> def foo(): return 0
... 
>>> var[3]
't'
>>> foo[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'function' object is not subscriptable

Điều đó có nghĩa là không có đăng ký hoặc nói các yếu tố functiongiống như chúng xảy ra theo trình tự; và chúng tôi không thể truy cập chúng như chúng tôi, với sự giúp đỡ của [].

Cũng thế; như mipadi đã nói trong câu trả lời của mình; Về cơ bản nó có nghĩa là đối tượng thực hiện __getitem__()phương thức. (nếu nó được đăng ký). Do đó, lỗi được tạo ra:

arr.append["HI"]

LoạiError: đối tượng 'buildin_feft_or_method' không thể đăng ký


7

tôi đã có vấn đề tương tự. tôi đã làm

arr = []
arr.append["HI"]

Vì vậy, sử dụng [đã gây ra lỗi. Nó nênarr.append("HI")


3

Như một hệ quả tất yếu cho các câu trả lời trước đây ở đây, rất thường đây là một dấu hiệu cho thấy bạn có một danh sách (hoặc chính tả, hoặc đối tượng có thể đăng ký khác) khi bạn không.

Ví dụ: giả sử bạn có một hàm sẽ trả về một danh sách;

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']

Bây giờ khi bạn gọi hàm đó và something_happens()vì một lý do nào đó không trả về Truegiá trị, điều gì xảy ra? Sự ifthất bại, và vì vậy bạn rơi qua; gimme_thingskhông rõ ràng returnbất cứ điều gì - vì vậy trong thực tế, nó sẽ hoàn toàn return None. Sau đó, mã này:

things = gimme_things()
print("My first thing is {0}".format(things[0]))

sẽ thất bại với " NoneTypeđối tượng không phải là subscriptable" bởi vì, tốt, thingsNonevà do đó bạn đang cố gắng làm None[0]mà không có ý nghĩa vì ... những gì được thông báo lỗi nói.

Có hai cách để sửa lỗi này trong mã của bạn - cách đầu tiên là tránh lỗi bằng cách kiểm tra xem thingsthực tế có hợp lệ không trước khi thử sử dụng nó;

things = gimme_things()
if things:
    print("My first thing is {0}".format(things[0]))
else:
    print("No things")  # or raise an error, or do nothing, or ...

hoặc tương đương bẫy TypeErrorngoại lệ;

things = gimme_things()
try:
    print("My first thing is {0}".format(things[0]))
except TypeError:
    print("No things")  # or raise an error, or do nothing, or ...

Một cách khác là thiết kế lại gimme_thingsđể bạn chắc chắn rằng nó luôn trả về một danh sách. Trong trường hợp này, đó có lẽ là thiết kế đơn giản hơn bởi vì điều đó có nghĩa là nếu có nhiều nơi bạn gặp lỗi tương tự, chúng có thể được giữ đơn giản và thành ngữ.

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']
    else:  # make sure we always return a list, no matter what!
        logging.info("Something didn't happen; return empty list")
        return []

Tất nhiên, những gì bạn đặt trong else:chi nhánh phụ thuộc vào trường hợp sử dụng của bạn. Có lẽ bạn nên nêu ra một ngoại lệ khi something_happens()thất bại, để làm cho nó rõ ràng và rõ ràng hơn khi một cái gì đó thực sự đã sai? Thêm ngoại lệ vào mã của riêng bạn là một cách quan trọng để cho bạn biết chính xác điều gì xảy ra khi có lỗi!

(Chú ý cũng cách sửa chữa sau này vẫn không hoàn toàn sửa chữa các lỗi - nó ngăn cản bạn cố gắng subscript Nonenhưng things[0]vẫn là một IndexErrorkhi thingslà một danh sách rỗng Nếu bạn có một. tryBạn có thể làm except (TypeError, IndexError)để bẫy nó, quá.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.