2012-07-02 22 views
103

Tôi biết rằng tôi có thể sử dụng: isinstance(x, str) trong python-3.x nhưng tôi cần phải kiểm tra xem một cái gì đó là một chuỗi trong python-2.x là tốt . Sẽ isinstance(x, str) hoạt động như mong đợi trong python-2.x? Hoặc tôi sẽ cần phải kiểm tra phiên bản và sử dụng isinstance(x, basestr)?Làm thế nào để kiểm tra xem biến là chuỗi với python 2 và 3 tương thích

Cụ thể, trong python-2.x:

>>>isinstance(u"test", str) 
False 

và python-3.x không có u"foo"

+1

u "" cú pháp cho literals Unicode được giới thiệu lại bằng Python 3.3 – jfs

+0

Chính xác, đây là một vấn đề khó xử để giải quyết ... cảm ơn. – ranman

+0

@ J.F.Sebastian, tôi đọc điều đó và LOL-ed. :-) Ah, những chuỗi pesky ... –

Trả lời

132

Nếu bạn viết mã tương thích 2.x và 3.x, có thể bạn sẽ muốn sử dụng six:

from six import string_types 
isinstance(s, string_types) 
+0

Xin lỗi tôi hơi bối rối về kết quả sau. '>>> isinstance (u "foo", string_types) ' ' TRUE' ' >>> isinstance (u "foo" .encode ("utf-8"), string_types) ' 'Đúng ' Tôi đã dự kiến ​​isinstance (u" foo ", string_types) trả về false. –

+1

@ Chandler.Huang câu hỏi này là về việc xác định 'str' và' unicode' trên Python 2, hoặc 'str' trên Python 3. Nếu bạn không muốn' unicode' đếm trên Python 2, chỉ cần sử dụng 'str'. – ecatmur

+0

@ecatmur woops, cảm ơn! xóa nó, do đó, không ai bị nhầm lẫn – runDOSrun

6

Có thể sử dụng một cách giải quyết như

def isstr(s): 
    try: 
     return isinstance(s, basestring) 
    except NameError: 
     return isinstance(s, str) 
+0

Xin lỗi để lỗi bạn nhưng 'isinstance (u'hello ', basestr)' yields 'SyntaxError: cú pháp không hợp lệ' cho tôi với Python 3.2.3 trong Window 7 .. bất kỳ ý tưởng tại sao điều này sẽ? Nó không có vẻ giống như 'u' - tôi nhận được lỗi này với' str' và 'basestr' – Levon

+1

@Levon Không vấn đề gì :) Đó là vì [Python3 không có cú pháp đó] (http: //docs.python .org/release/3.0.1/whatsnew/3.0.html # text-vs-data-thay-of-unicode-vs-8-bit), như 'str' trong Python3 là theo định nghĩa Unicode. Theo đó, không có loại 'basestring', do đó' NameError' bị bắt trong đoạn mã của tôi. –

+0

Bây giờ nó có cú pháp như noop. trong 3.3 – ranman

17

Đây là câu trả lời của @Lev Levitsky, được viết lại một chút.

try: 
    isinstance("", basestring) 
    def isstr(s): 
     return isinstance(s, basestring) 
except NameError: 
    def isstr(s): 
     return isinstance(s, str) 

Các thử nghiệm try/except được thực hiện một lần, và sau đó định nghĩa một hàm mà luôn luôn làm việc và càng nhanh càng tốt.

EDIT: Trên thực tế, chúng tôi thậm chí không cần gọi isinstance(); chúng ta chỉ cần để đánh giá basestring và xem liệu chúng ta có được một NameError:

try: 
    basestring # attempt to evaluate basestring 
    def isstr(s): 
     return isinstance(s, basestring) 
except NameError: 
    def isstr(s): 
     return isinstance(s, str) 

Tôi nghĩ rằng đó là dễ dàng hơn để làm theo với các cuộc gọi đến isinstance(), mặc dù.

+0

'isinstance (" ", basestring)' là những gì tôi có nghĩa là "gọi". Dù sao, +1. –

+1

Python là một ngôn ngữ rất năng động, và tôi không nghĩ rằng nó có vẻ xấu ở tất cả để có một bài kiểm tra như thế. Đây là một kỹ thuật hữu ích để tìm ra điều gì đó trong một thời gian, và dựa trên đó, thiết lập một hàm luôn luôn đúng. Cảm ơn vì +1. – steveha

+5

Tôi sẽ viết nó như sau: 'try: string_types = basestring ngoại trừ NameError: string_types = str' – jfs

5

Bạn có thể lấy lớp của một đối tượng bằng cách gọi object.__class__, vì vậy để kiểm tra xem đối tượng là kiểu chuỗi mặc định:

isinstance(object,"".__class__) 

Và Bạn có thể đặt dòng sau vào phía trên cùng của Mã của bạn để dây được bao bọc bởi dấu ngoặc kép là trong unicode trong python 2:

from __future__ import unicode_literals 
+0

Tôi giải pháp này khá một chút. Tôi thấy nó có thể hữu ích để xác định str = "" .__ class__, bây giờ cho phép isinstance (object, str) được viết bình thường, và cũng đảm bảo rằng str (object) sẽ trả về một chuỗi unicode trong cả Python 2 và Python 3. – amicitas

+0

Điều này không hoạt động khi phân tích cú pháp XML: 'some_element.text' là 'str' nhưng so sánh với 'unicode' sẽ thất bại – vault

+0

Không hoạt động với chuỗi unicode trên python 2: isinstance (u'XXX ',' ' .__ class__) == Sai – Fil

66

phương pháp ngắn gọn nhất mà tôi đã tìm thấy mà không dựa vào gói như sáu, là:

try: 
    basestring 
except NameError: 
    basestring = str 

sau đó, giả sử bạn đã kiểm tra cho chuỗi bằng Python 2 theo cách chung nhất,

isinstance(s, basestring) 

bây giờ sẽ còn làm việc cho Python 3+.

+1

Tôi thực sự thích cách tiếp cận này. – ranman

+0

tôi cũng vậy ... đơn giản, thanh lịch, hiệu quả! Cảm ơn;) – daveoncode

+6

Đối với py3, 'basestring = (str, bytes)' từ 'requests/compat.py' –

14

Điều gì về điều này, hoạt động trong mọi trường hợp?

isinstance(x, ("".__class__, u"".__class__)) 
+2

Tôi dường như đơn độc với tác giả, nhưng tôi nghĩ điều này khá thanh lịch. – holdenweb

+0

@holdenweb: Không và có - một thứ "dễ bị ảnh hưởng khi cần thiết" hack mà tôi nghĩ. – Dilettant

+0

Lý do tại sao tôi thích câu trả lời này là thân thiện với việc di chuyển từ python2 đến 3. – Tiagojdferreira

-3

loại (string) == str

trả về true nếu nó là một chuỗi, và false nếu không

+1

Không đúng cho Python 2, trong đó 'string' là một chuỗi unicode – lxop

2

Các future library thêm (để Python 2) tên tương thích, vì vậy bạn có thể tiếp tục viết Python 3.Bạn có thể đơn giản làm như sau:

from builtins import str 
isinstance(x, str) 

Để cài đặt nó, chỉ cần thực hiện pip install future.

Là một caveat, nó chỉ hỗ trợ python>=2.6, >=3.3, nhưng nó là hiện đại hơn six, mà chỉ recommended if using python 2.5

+1

Tôi đoán nó phải là' from' thay vì 'for'? – Cleb

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