Trong trăn có cách nào dễ dàng để biết liệu có gì đó không phải là một chuỗi không? Tôi cố gắng để chỉ: if x is not sequence
nhưng trăn không thích điều đóPython: kiểm tra xem một đối tượng có phải là một chuỗi
Trả lời
iter(x)
sẽ nâng cao một TypeError
nếu x
không thể được lặp trên - nhưng kiểm tra rằng "chấp nhận" bộ và từ điển, mặc dù nó là "từ chối" không trình tự khác chẳng hạn như None
và số. Mặt khác, các chuỗi (hầu hết các ứng dụng muốn xem xét "các mục đơn lẻ" chứ không phải chuỗi) là trong chuỗi thực tế (vì vậy, bất kỳ kiểm tra nào, trừ khi được đặc biệt cho chuỗi, sẽ xác nhận rằng chúng là) . Vì vậy, các kiểm tra đơn giản như vậy thường không đủ.
Trong Python 2.6 trở lên, lớp cơ sở trừu tượng được giới thiệu và trong số các tính năng mạnh khác, chúng cung cấp hỗ trợ tốt hơn, có hệ thống cho "kiểm tra danh mục" như vậy.
>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance((), collections.Sequence)
True
>>> isinstance(23, collections.Sequence)
False
>>> isinstance('foo', collections.Sequence)
True
>>> isinstance({}, collections.Sequence)
False
>>> isinstance(set(), collections.Sequence)
False
Bạn sẽ lưu ý chuỗi là vẫn coi là "một chuỗi" (vì họ là), nhưng ít nhất bạn có được dicts và bộ ra khỏi đường. Nếu bạn muốn loại trừ chuỗi khỏi khái niệm "chuỗi tự động" của mình, bạn có thể sử dụng collections.MutableSequence
(nhưng cũng loại trừ bộ dữ liệu, như chuỗi, là chuỗi, nhưng không thể thay đổi) hoặc làm rõ ràng:
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
Phần thưởng thức và phục vụ nóng! -)
Lưu ý rằng ví dụ mã này sẽ trả về kết quả sai đối với các đối tượng thực hiện giao thức chuỗi nhưng không liên quan đến ABC collections.Sequence'. –
Yep: khác với ABC đơn giản, Sequence không thực hiện phương thức lớp '__subclasshook__', vì vậy nó sẽ không bao giờ tự động nhận ra một lớp đã chọn không đăng ký' với nó (hoặc kế thừa từ nó) để biết được sự hiểu biết của một lớp '__getitem__' chấp nhận số nguyên và lát, tăng' IndexError' trên các chỉ mục sai, vv - tất cả bạn cần loại trừ 'dict' và' set', về cơ bản (rằng _do_ dường như "thực hiện chuỗi giao thức "nếu bạn chỉ cần làm nội tâm ... nhưng sau đó hóa ra là không! -). –
Bộ dễ bị loại trừ vì chúng không có '__getitem__', nhưng ánh xạ khó hơn nhiều. Kiểm tra tốt nhất tôi đã nhìn thấy có lẽ là tìm kiếm 'keys', giống như' dict.update', nhưng vẫn còn rất nhiều điều mong muốn. – user2357112
Tại sao bạn làm điều này? Cách thông thường ở đây là yêu cầu một loại điều nhất định (Một chuỗi hoặc một số hoặc một đối tượng giống như tệp, v.v.) và sau đó sử dụng nó mà không kiểm tra bất kỳ thứ gì. Trong Python, chúng ta thường không sử dụng các lớp để mang thông tin ngữ nghĩa mà chỉ sử dụng các phương thức được định nghĩa (được gọi là "gõ vịt"). Chúng tôi cũng thích các API nơi chúng tôi biết chính xác những gì mong đợi; sử dụng các đối số từ khóa, tiền xử lý, hoặc định nghĩa một hàm khác nếu bạn muốn thay đổi cách một hàm hoạt động.
Đó là ràng buộc chuyển nhượng. Nếu đối số mà chúng ta truyền vào không phải là int, long hay sequence, chúng ta cần phải tạo ra một 'TypeError' – nicotine
@nicotine, nhận ra rằng phép gán này chỉ ra một thiết kế thường không phải là nonidiomatic và mong manh. Hãy xem xét trường hợp bình thường, nơi một đối tượng phải chính xác là một loại điều. Nếu một tham số được coi là một chuỗi nhưng bạn nhận được một int, khi bạn lập chỉ mục hoặc lặp lại nó, bạn sẽ nhận được một 'TypeError'. Tương tự, nếu bạn cố gắng thực hiện các phép toán số nguyên với một chuỗi bạn muốn. –
Cung cấp một API nhất quán (khi có thể) chỉ mong đợi một loại điều cho phép bạn viết mã đơn giản hơn mà vẫn tăng lỗi khi có sự cố nhưng mạnh mẽ hơn ở chỗ nó hỗ trợ các kiểu mà bạn không nghĩ đến. mục tiêu (ví dụ, một số lớp tùy chỉnh thực hiện '__len__' và' __getitem__' sẽ hoạt động như một chuỗi.) –
Các Python 2.6.5 documentation mô tả các loại trình tự sau: chuỗi, chuỗi Unicode, danh sách, bộ đệm, bộ đệm và xrange.
def isSequence(obj):
return type(obj) in [str, unicode, list, tuple, buffer, xrange]
Vấn đề với câu trả lời này là nó sẽ không phát hiện chuỗi không phải là các loại nội trang. Một chuỗi "Python" là bất kỳ đối tượng nào thực hiện các phương thức cần thiết để đáp ứng các hoạt động chuỗi. – intuited
Ngoài ra, sử dụng 'isinstance' thay cho' type' để hỗ trợ các lớp con. – bfontaine
tại sao hỏi tại sao
thử nhận được một chiều dài và nếu ngoại lệ trả về false
def haslength(seq):
try:
len(seq)
except:
return False
return True
Một tập hợp 'có độ dài nhưng không phải là một chuỗi. – bfontaine
Kể từ Python "tuân thủ" gõ vịt, một trong những phương pháp này là để kiểm tra xem một đối tượng có một số thành viên (phương pháp).
Một chuỗi có độ dài, có chuỗi các mục và hỗ trợ cắt [doc]. Vì vậy, nó sẽ là như thế này:
def is_sequence(obj):
t = type(obj)
return hasattr(t, '__len__') and hasattr(t, '__getitem__')
# additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__')
Họ đều là những phương pháp đặc biệt, __len__()
nên trả lại số hạng mục, __getitem__(i)
nên trở về một mục (theo thứ tự đó là i mục -thứ, nhưng không phải với lập bản đồ), __getitem__(slice(start, stop, step))
phải trả về các hậu tố và __setitem__
và __delitem__
như bạn mong đợi.Đây là một hợp đồng như vậy, nhưng liệu đối tượng có thực sự làm những điều này hay không phụ thuộc vào việc liệu đối tượng có tuân theo hợp đồng hay không.
Lưu ý rằng, hàm ở trên cũng sẽ trả về True
để ánh xạ, ví dụ: dict
, vì ánh xạ cũng có các phương thức này. Để khắc phục điều này, bạn có thể làm một nặng công việc:
def is_sequence(obj):
try:
len(obj)
obj[0:0]
return True
except TypeError:
return False
Nhưng hầu hết thời gian bạn không cần điều này, chỉ cần làm những gì bạn muốn là nếu đối tượng là một chuỗi và bắt một ngoại lệ nếu bạn ước. Điều này là nhiều hơn pythonic.
Điểm quan trọng về dict là nếu bạn đối xử với nó như một chuỗi bạn sẽ chỉ nhận được các khóa, không phải là các giá trị, và thông tin sẽ bị mất. –
Nếu sử dụng 'hasattr()', bạn cần phải kiểm tra loại đối tượng cho các phương pháp ma thuật, không phải đối tượng đó. Xem [Python 2] (https://docs.python.org/2/reference/datamodel.html#special-method-lookup-for-new-style-classes) và [Python 3] (https: // docs Tài liệu .python.org/3/reference/datamodel.html # special-method-lookup) về cách các phương thức đặc biệt được tìm kiếm. – augurar
@augurar Cảm ơn người đàn ông – BornToCode
Tôi nghĩ rằng đoạn mã dưới đây làm những gì bạn muốn:
def is_sequence(obj):
return hasattr(type(obj), '__iter__')
Nên là 'hasattr (type (obj), '__iter __')', xem [bình luận này] (https://stackoverflow.com/questions/2937114/#comment71833903_31043360). – augurar
- 1. Kiểm tra xem có phải là một đối tượng
- 2. python 3: cách kiểm tra xem đối tượng có phải là một hàm không?
- 3. Kiểm tra xem một chuỗi có phải là số
- 4. Kiểm tra xem đối tượng Ruby có phải là Boolean
- 5. Python: Cách kiểm tra xem một chuỗi có phải là một IRI hợp lệ không?
- 6. Kiểm tra xem một đối tượng có phải là một mảng nguyên thủy Java trong Clojure
- 7. Cách kiểm tra xem đối tượng có phải là một mảng của một loại nhất định
- 8. Kiểm tra xem đối tượng là một số hoặc boolean
- 9. Kiểm tra xem một đối tượng là một Enum
- 10. Kiểm tra xem đây có phải là
- 11. Cách kiểm tra xem ký tự trong chuỗi có phải là một chữ cái không? Python
- 12. Cách kiểm tra xem đối tượng có phải là một loại nhất định
- 13. Kiểm tra xem đối tượng có phải là danh sách các danh sách trong python không?
- 14. Python - kiểm tra xem đối tượng có phải là hàm dựng sẵn hay không
- 15. Mongoose: kiểm tra xem đối tượng có phải là đối tượng mongoose
- 16. python: cách kiểm tra xem một dòng có phải là một dòng trống không
- 17. Làm thế nào để kiểm tra xem một đối tượng là một đối tượng máy phát trong python?
- 18. Kiểm tra xem một đối tượng có tồn tại
- 19. Kiểm tra xem tham số có phải là một mô-đun Python không?
- 20. Kiểm tra xem chuỗi có phải là một cách viết tắt có thể cho tên
- 21. Kiểm tra xem char có phải là một dòng mới
- 22. Chức năng kiểm tra xem chuỗi có phải là ngày
- 23. Kiểm tra xem biến có phải là ngày có Twig
- 24. Cách tốt nhất để kiểm tra xem một đối tượng có phải là một mảng hay không trong Javascript?
- 25. Kiểm tra xem tệp có phải là một đường ống có tên (nămo) trong python không?
- 26. Làm cách nào để kiểm tra xem một đối số đã cho có phải là đối tượng datetime.date không?
- 27. Kiểm tra xem đối tượng có phải là bộ sưu tập chung chung không
- 28. Python có phải là một đối tượng không?
- 29. Kiểm tra xem tệp có phải là liên kết tượng trưng trong python
- 30. Cách kiểm tra xem đối tượng đã cho là đối tượng hoặc Mảng trong chuỗi JSON
liên quan: Trong python, làm thế nào để xác định xem một biến là Iterable? http://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-a-variable-is-iterable/1952481#1952481 – miku
Đúng, nhưng trong khi tất cả các chuỗi có thể lặp lại không phải tất cả các lần lặp lại là chuỗi (bộ và dicts là các thùng chứa có thể lặp lại được tích hợp không phải là trình tự, ví dụ). –