2009-04-01 37 views

Trả lời

153
isinstance() 

Trong trường hợp của bạn, isinstance("this is a string", str) sẽ trả lại True.

Bạn cũng có thể muốn đọc này: http://www.canonical.org/~kragen/isinstance/

+4

Tôi muốn bạn (OP) nên * chắc chắn * đọc liên kết được tham chiếu, cung cấp nhiều chi tiết về lý do kiểm tra loại đối tượng thường là ý tưởng tồi, và những gì bạn có thể nên làm thay vào đó. –

+3

từ bộ nhớ đang phục hồi (obj, basestring) sẽ lấy chuỗi unicode quá ... –

+2

bạn nên sử dụng basestr, không str. nếu không bạn sẽ không chọn unicode. (mặc dù cho 3.x tôi nghĩ str * là * basestr) – hasen

4

Bạn đang ở rất gần! string là một mô-đun, không phải là một loại. Có thể bạn muốn so sánh các loại obj chống lại các đối tượng kiểu cho dây, cụ thể là str:

type(obj) == str # this works because str is already a type 

Hoặc:

type(obj) == type('') 

Lưu ý, trong Python 2, nếu obj là một loại unicode, sau đó không của những điều trên sẽ hoạt động. Cũng sẽ không isinstance(). Xem nhận xét của John về bài đăng này để biết cách giải quyết vấn đề này ... Tôi đã cố nhớ nó trong khoảng 10 phút, nhưng đã có một khối bộ nhớ!

+2

Sử dụng lệnh basestring với isinstance() để nhận cả str và unicode. –

+0

-1 vì không đề cập đến typecheck là ý tưởng tồi – nosklo

2

tôi nghĩ rằng điều này sẽ làm điều đó

if isinstance(obj, str) 
+0

-1 vì không đề cập đến typecheck là một ý tưởng tồi – nosklo

22

Đối với các loại khác, hãy kiểm tra các mô-đun types:

>>> import types 
>>> x = "mystring" 
>>> isinstance(x, types.StringType) 
True 
>>> x = 5 
>>> isinstance(x, types.IntType) 
True 
>>> x = None 
>>> isinstance(x, types.NoneType) 
True 

T.B. Typechecking là một ý tưởng tồi.

32

isinstance công trình:

if isinstance(obj, MyClass): do_foo(obj) 

nhưng, cần lưu ý: nếu nó trông giống như một con vịt, và nếu nó có vẻ giống như một con vịt, nó là một con vịt.

EDIT: Đối với Không loại, bạn có thể chỉ cần làm:

if obj is None: obj = MyClass() 
+0

'def distance_from_zero (n): nếu isinstance (n, int) hoặc isinstance (n, float) : trở abs (n) khác: trở lại "Nope" in distance_from_zero (True) ' này trả về một "1" thay vì "Không". Làm thế nào để có được điều này? –

+0

Nếu bạn muốn sử dụng 'isinstance' nhưng cũng kiểm tra' None' thì 'isinstance (obj, (MyClass, type (None)))' hoạt động. 'types.NoneType' đã được loại bỏ khỏi Python 3 vì vậy nó không phải là di động như' type (None) 'để có được một tham chiếu đến' NoneType'. –

+0

Nó làm việc cho tôi. Cảm ơn :) –

10

Bạn luôn có thể sử dụng type(x) == type(y) lừa, nơi y là một cái gì đó với loại được biết đến.

# check if x is a regular string 
type(x) == type('') 
# check if x is an integer 
type(x) == type(1) 
# check if x is a NoneType 
type(x) == type(None) 

Thường có cách tốt hơn để làm điều đó, đặc biệt là với bất kỳ con trăn nào gần đây. Nhưng nếu bạn chỉ muốn nhớ một điều, bạn có thể nhớ điều đó.

Trong trường hợp này, cách tốt hơn sẽ là:

# check if x is a regular string 
type(x) == str 
# check if x is either a regular string or a unicode string 
type(x) in [str, unicode] 
# alternatively: 
isinstance(x, basestring) 
# check if x is an integer 
type(x) == int 
# check if x is a NoneType 
x is None 

Lưu ý trường hợp cuối cùng: chỉ có một thể hiện của NoneType trong python, và đó là None.Bạn sẽ thấy NoneType rất nhiều trong trường hợp ngoại lệ (TypeError: 'NoneType' object is unsubscriptable - xảy ra với tôi tất cả các thời gian ..) nhưng bạn sẽ hầu như không bao giờ cần phải tham khảo nó trong mã.

Cuối cùng, như fengshaun chỉ ra, gõ kiểm tra trong python không phải luôn luôn là một ý tưởng tốt. Đó là thêm pythonic để chỉ sử dụng giá trị như thể nó là loại bạn mong đợi, và bắt (hoặc cho phép tuyên truyền) trường hợp ngoại lệ là kết quả từ nó.

+1

Đối với những gì nó có giá trị, isinstance() là cách ưa thích của việc kiểm tra các loại trong Python (khi bạn phải làm điều đó). –

3

tôi sử dụng type(x) == type(y)

Ví dụ, nếu tôi muốn kiểm tra một cái gì đó là một mảng:

type(x) == type([]) 

chuỗi kiểm tra:

type(x) == type('') or type(x) == type(u'') 

Nếu bạn muốn kiểm tra chống lại Không, sử dụng là

x is None 
+0

-1 vì không đề cập đến typecheck là một ý tưởng tồi – nosklo

+0

huh? tại sao nó là một ý tưởng tồi nói chung? Nó chỉ là một ý tưởng tồi cho chuỗi (cho trước 3.0) vì có hai loại chuỗi, str và unicode. Đối với mảng, đó là một ý tưởng hay. – hasen

+0

@ hasen: đó là một ý tưởng tồi tổng thể. Điều gì sẽ xảy ra nếu tôi định nghĩa kiểu của riêng tôi hoạt động giống như một mảng nhưng, nói, lấy các giá trị từ một cơ sở dữ liệu? Mã của bạn sẽ thất bại với loại của tôi không có lý do. – nosklo

28

Đầu tiên, tránh tất cả các so sánh kiểu. Chúng rất, rất hiếm khi cần thiết. Đôi khi, họ giúp kiểm tra các loại tham số trong một hàm - thậm chí là hiếm. Dữ liệu loại sai sẽ làm tăng ngoại lệ và đó là tất cả những gì bạn cần.

Tất cả các chức năng chuyển đổi cơ bản sẽ ánh xạ bằng chức năng loại.

type(9) is int 
type(2.5) is float 
type('x') is str 
type(u'x') is unicode 
type(2+3j) is complex 

Có một vài trường hợp khác.

isinstance('x', basestring) 
isinstance(u'u', basestring) 
isinstance(9, int) 
isinstance(2.5, float) 
isinstance((2+3j), complex) 

Không, BTW, không bao giờ cần bất kỳ loại kiểm tra kiểu nào. Không có trường hợp duy nhất của NoneType. Đối tượng None là Singleton. Chỉ cần kiểm tra xem None

variable is None 

BTW, không sử dụng thông tin nói trên. Sử dụng các ngoại lệ thông thường và tính đa hình tự nhiên của Python.

+2

Nếu bạn đang xác thực các đầu vào từ DSL, bạn cần tất cả điều này, ngay cả 'NoneType'. Điều gì sẽ xảy ra nếu tham số có thể là 'str',' unicode' hoặc 'None'? 'isinstance (x, (str, unicode, types.NoneType))' sạch hơn nhiều so với việc kiểm tra 'None'. Nếu bạn đang xây dựng các công cụ để tính toán hoãn lại hoặc nếu bạn chuẩn bị khởi chạy quá trình dài hoặc tốn nhiều tài nguyên, thì rất có giá trị để nắm bắt các lỗi 'loại' trước thời hạn, trong một số bước xác thực tùy chỉnh. Đây là một phần quan trọng trong hầu hết các dự án điện toán khoa học mà tôi từng làm. Trong số tất cả các dự án dev tôi đã thấy, nhiều hơn những gì cần thiết hơn là không. – ely

5

Đó là bởi vì bạn phải viết

s="hello" 
type(s) == type("") 

loại chấp nhận một thể hiện và trả về kiểu của nó. Trong trường hợp này, bạn phải so sánh hai loại của các cá thể.

Nếu bạn cần thực hiện kiểm tra ưu tiên, bạn nên kiểm tra giao diện được hỗ trợ hơn loại đó.

Loại này không thực sự cho bạn biết nhiều, ngoài thực tế là mã của bạn muốn một thể hiện của một loại cụ thể, bất kể thực tế là bạn có thể có một thể hiện khác loại hoàn toàn khác thực hiện cùng một giao diện.

Ví dụ, giả sử bạn có mã này

def firstElement(parameter): 
    return parameter[0] 

Bây giờ, giả sử bạn nói: Tôi muốn mã này chỉ chấp nhận một tuple.

import types 

def firstElement(parameter): 
    if type(parameter) != types.TupleType: 
     raise TypeError("function accepts only a tuple") 
    return parameter[0] 

Điều này làm giảm khả năng sử dụng lại quy trình này. Nó sẽ không hoạt động nếu bạn vượt qua một danh sách, hoặc một chuỗi, hoặc một numpy.array.Một cái gì đó tốt hơn sẽ là

def firstElement(parameter): 
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))): 
     raise TypeError("interface violation") 
    return parameter[0] 

nhưng không có điểm nào khi thực hiện nó: tham số [0] sẽ ngoại trừ trường hợp bạn không hài lòng ... tất nhiên trừ khi bạn muốn ngăn chặn tác dụng phụ hoặc phải phục hồi từ các cuộc gọi mà bạn có thể gọi trước khi không thành công. Ví dụ (ngu ngốc), chỉ để làm cho vấn đề:

def firstElement(parameter): 
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))): 
     raise TypeError("interface violation") 
    os.system("rm file") 
    return parameter[0] 

trong trường hợp này, mã của bạn sẽ tăng ngoại lệ trước khi chạy cuộc gọi system(). Nếu không có kiểm tra giao diện, bạn có thể đã xóa tệp và sau đó đưa ra ngoại lệ.

+0

Cảm ơn bạn đã chỉ ra cách ưa thích thực sự để kiểm tra giao diện. Nhiều người trong số các câu trả lời ở đây đề cập đến nó, nhưng ít đưa ra ví dụ về những gì tốt để thay thế. Nó vẫn không trả lời câu hỏi cá nhân của tôi trực tiếp (Tôi đang cố gắng tách một danh sách các chuỗi, chứa nhiều, các mục có ý nghĩa, từ một chuỗi, trong đó có nhiều, không có ý nghĩa các mặt hàng. – Nick

1

Loại không hoạt động trên một số lớp nhất định. Nếu bạn không chắc chắn về loại của đối tượng sử dụng phương pháp __class__, như vậy:

>>>obj = 'a string' 
>>>obj.__class__ == str 
True 

Cũng xem bài viết này - http://www.siafoo.net/article/56

0

Để có được loại, sử dụng __class__ thành viên, như trong unknown_thing.__class__

Nói về cách gõ vịt là vô dụng ở đây vì nó không trả lời một câu hỏi hoàn hảo. Trong mã ứng dụng của tôi, tôi không bao giờ cần biết loại thứ gì đó, nhưng nó vẫn hữu ích khi có một cách để tìm hiểu kiểu của một đối tượng. Đôi khi tôi cần phải có được lớp thực tế để xác nhận một bài kiểm tra đơn vị. Đánh máy vịt được theo cách đó bởi vì tất cả các đối tượng có thể có cùng một API, nhưng chỉ có một đối tượng là chính xác. Ngoài ra, đôi khi tôi đang duy trì mã của người khác, và tôi không biết tôi đã bị loại đối tượng gì. Đây là vấn đề lớn nhất của tôi với các ngôn ngữ được gõ động như Python. Phiên bản 1 rất dễ dàng và nhanh chóng phát triển. Phiên bản 2 là một nỗi đau trong bánh, đặc biệt là nếu bạn không viết phiên bản 1. Vì vậy, đôi khi, khi tôi đang làm việc với một chức năng tôi đã không viết, tôi cần phải biết loại tham số, chỉ vì vậy tôi biết những phương pháp tôi có thể gọi trên đó.

Đó là nơi tham số __class__ có ích. Điều đó (theo như tôi có thể nói) là cách tốt nhất (có lẽ là cách duy nhất) để có được kiểu của một đối tượng.

3

Sử dụng str thay vì chuỗi

type (obj) == str 

Giải thích

>>> a = "Hello" 
>>> type(a)==str 
True 
>>> type(a) 
<type 'str'> 
>>> 
0

Bạn có thể so sánh các lớp học với trình độ kiểm tra.

#!/usr/bin/env python 
#coding:utf8 

class A(object): 
    def t(self): 
     print 'A' 
    def r(self): 
     print 'rA', 
     self.t() 

class B(A): 
    def t(self): 
     print 'B' 

class C(A): 
    def t(self): 
     print 'C' 

class D(B, C): 
    def t(self): 
     print 'D', 
     super(D, self).t() 

class E(C, B): 
    pass 

d = D() 
d.t() 
d.r() 

e = E() 
e.t() 
e.r() 

print isinstance(e, D) # False 
print isinstance(e, E) # True 
print isinstance(e, C) # True 
print isinstance(e, B) # True 
print isinstance(e, (A,)) # True 
print e.__class__ >= A, #False 
print e.__class__ <= C, #False 
print e.__class__ < E, #False 
print e.__class__ <= E #True 
Các vấn đề liên quan