Câu trả lời:
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.
[
... ]
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)
.
hasattr
sẽ 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 try
khối bằng một except TypeError
.
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ý
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).
Ý 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ố function
giố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ý
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")
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ề True
giá trị, điều gì xảy ra? Sự if
thất bại, và vì vậy bạn rơi qua; gimme_things
không rõ ràng return
bấ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, things
là None
và 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 things
thự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 TypeError
ngoạ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 None
nhưng things[0]
vẫn là một IndexError
khi things
là một danh sách rỗng Nếu bạn có một. try
Bạn có thể làm except (TypeError, IndexError)
để bẫy nó, quá.)
hasattr(SomeClassWithoutGetItem, '__getitem__')
để xác định nếu một điều là có thể đăng ký?