Python kiểm tra xem có bất kỳ loại nào trong danh sách không?


87

Tôi phải làm như thế nào:

var = 7.0
var_is_good = isinstance(var, classinfo1) or isinstance(var, classinfo2) or isinstance(var, classinfo3) or ... or  isinstance(var, classinfoN)

Có vẻ ngớ ngẩn khi tôi không thể vượt qua danh sách classinfo's:

var_is_good = isinstanceofany( var, [classinfo1, classinfo2, ... , classinfoN] )

Vậy isinstanceofanychức năng là gì?


Nếu nó cộng như một số, trừ như một số, nhân như một số ... tại sao bạn cần biết nó là một số? Xem vịt gõ để biết thêm chi tiết.
Makoto

Trường hợp sử dụng cụ thể của tôi đang có một hàm trả về một (hàm trả về ( numberHOẶC nó trả về một biểu thức giao cảm)). Tôi muốn kiểm tra xem hàm tôi đã tạo có thực hiện những gì nó phải làm khi tôi chuyển nó cho các hàm khác hay không.
D Adams

Tại sao hàm của bạn không trả về một cái gì đó thuần nhất? Đó là mùi ở đây; bạn có thể trở nên nhanh chóng và lỏng lẻo với cách gõ vịt, nhưng bạn nên nhất quán trong những gì bạn trả lại.
Makoto

Tôi đoán rằng tôi luôn có thể trả về một biểu thức giao hưởng mà đôi khi đánh giá bằng một con số và đôi khi có các biến số bên trong nó.
D Adams

Đó là những gì tôi nghĩ rằng bạn muốn làm ở đây; thay vì trả về nhiều kiểu khác nhau, hãy trả về một kiểu và nếu cần, hãy giảm nó thành một số.
Makoto

Câu trả lời:


191

isinstance()mất một tuple của lớp dành cho đối số thứ hai. Nó sẽ trả về true nếu đối số đầu tiên là một phiên bản của bất kỳ kiểu nào trong chuỗi đó:

isinstance(var, (classinfo1, classinfo2, classinfo3))

Nói cách khác, isinstance() đã cung cấp chức năng này, ngay lập tức.

Từ isinstance()tài liệu :

Nếu classinfo không phải là một đối tượng lớp cũng không phải là một đối tượng kiểu, nó có thể là một bộ của các đối tượng lớp hoặc kiểu hoặc có thể chứa đệ quy các bộ khác như vậy (các kiểu trình tự khác không được chấp nhận).

Nhấn mạnh của tôi; lưu ý tính chất đệ quy; (classinfo1, (classinfo2, classinfo3))cũng là một lựa chọn hợp lệ.


Hữu ích, cảm ơn bạn!
Yaakov Bressler

11

Bạn đã khá gần với tiêu đề câu hỏi của bạn rồi. Bạn có thể sử dụng anyvà một danh sách:

var = 7.0
var_is_good = any([isinstance(var, classinfo1),
                   isinstance(var, classinfo2),
                   isinstance(var, classinfo3), ...
                   isinstance(var, classinfoN)])

Nhưng nhìn vào tài liệu isinstancetiết lộ:

Trả về true nếu đối số đối tượng là một thể hiện của đối số classinfo hoặc của một lớp con (trực tiếp, gián tiếp hoặc ảo) của chúng. Nếu đối tượng không phải là đối tượng của kiểu đã cho, hàm luôn trả về giá trị false. Nếu classinfo không phải là một lớp (đối tượng kiểu), nó có thể là một bộ nhiều đối tượng kiểu hoặc có thể chứa đệ quy các bộ khác như vậy (các kiểu trình tự khác không được chấp nhận). Nếu classinfo không phải là một kiểu hoặc nhiều kiểu và các bộ như vậy, thì một ngoại lệ TypeError sẽ được đưa ra.

Điều này có nghĩa là cách tốt hơn để làm điều đó là

var = 7.0
var_is_good = isinstance(var, (classinfo1,
                               classinfo2,
                               classinfo3,
                               ...,
                               classinfoN))

2
Lặp lại isinstancechỉ với sự classinfothay đổi có vẻ không phải là Pythonic đối với tôi.
Makoto

1
Cố gắng var.__class__. Đó là điều bạn muốn? @Makoto: Tôi đồng ý. Không phải Pythonic chút nào!
flamenco

@Makoto Yup. Nhưng đó là thứ mà D Adams có thể dễ dàng tìm thấy bằng cách tìm kiếm "bất kỳ" trong tài liệu. Tôi đã mở rộng câu trả lời của mình sang phiên bản tốt hơn ... nhưng rõ ràng là Martijn Pieters đã nhanh hơn ... một lần nữa.
Martin Thoma

3
any()với một danh sách là .. vô nghĩa. Sử dụng biểu thức trình tạo nếu bạn phải sử dụng any(), sau đó ít nhất bạn nhận được lợi ích của việc thoát sớm.
Martijn Pieters

Tôi nghĩ rằng isinstancevới tuple là con đường để đi. Tôi chỉ muốn đề cập đến giải pháp anyvì nó dường như là những gì anh ấy đang yêu cầu trong tiêu đề.
Martin Thoma

4

Điều này sẽ giải quyết vấn đề của bạn:

valid_instance_types = <tuple of types you want to allow>
var_is_good = isinstance(var, valid_instance_types)

Dựa trên tài liệu, có rất nhiều cách bạn có thể chuyển các giá trị của các loại vào isinstance.

Bạn cũng có thể bị coi là khiêu gợi nếu bạn đang cố gắng thực hiện xác nhận phức tạp hơn mà đây chỉ là một phần.


isinstance () đã cung cấp chức năng này, hãy chuyển một tuple với tất cả các loại bắt buộc để kiểm tra làm đối số thứ 2
RFV

@ RFV5s Có .... đó là ví dụ mà tôi cung cấp ở đây cho thấy. Phản đối của bạn là gì?
Nathaniel Ford

1

Bạn thường không nên sử dụng isinstance, nhưng những gì bạn muốn làm có thể được thực hiện với bất kỳ hàm nội trang () nào .

var_is_good = any(isinstance(var, t) for t in [type1, type2, type3])

7
Điều này là quá mức cần thiết; isinstance()cung cấp chức năng ra khỏi hộp mà không cần sử dụng any().
Martijn Pieters

@MartijnPieters Tôi không nhận ra rằng isinstance có thể có nhiều loại, nhưng tôi cảm thấy câu trả lời vẫn là một câu hay vì câu hỏi có thể được hiểu rộng hơn là "Làm cách nào để kiểm tra xem có bất kỳ giá trị trả về nào từ một hàm cụ thể không với các thông số khác nhau là đúng "
Chad S.

Bạn có nên sử dụng hay không isinstance()là không liên quan.
RFV

@ChadS. Tôi muốn hỏi bạn tại sao bạn nghĩ rằng anh ta không nên sử dụng isinstance()? Cảm ơn bạn.
idature

Bởi vì python tránh kiểm tra loại. Đó là rất nhiều mã bổ sung (và các chu kỳ CPU) vì ít lợi ích. Gõ vịt được ưu tiên.
Chad S.
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.