Python перевіряє, чи немає будь-якого типу у списку?


86

Як зробити пітонічно:

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

Це здається дурним, я не можу просто передати список classinfo:

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

То яка isinstanceofanyфункція?


Якщо додається як число, віднімається як число, множиться як число ... навіщо потрібно знати, чи це число? Див качиної типізації для більш докладної інформації.
— Макото

Моїм конкретним випадком використання є наявність функції, яка повертає (функція, яка повертає (або numberАБО повертає вираз symp)). Я хочу перевірити, чи створена мною функція робить те, що вона повинна робити, коли я передаю її іншим функціям.
— D Adams

Чому ваша функція не повертає щось однорідне? Ось який тут запах; Ви можете швидко і розкуто набирати качок, але ви повинні бути послідовними у тому, що повертаєте.
— Макото

Я припускаю, що я завжди міг повернути вираз симпатії, який іноді обчислюється числом, а іноді в ньому залишаються змінні.
— D Adams

Це те, про що я думаю, що ти хочеш зробити тут; замість повернення декількох різних типів, поверніть один тип і, якщо потрібно, зменшіть його до числа.
— Макото

Відповіді:


190

isinstance()приймає кортеж класів для другого аргументу. Він поверне true, якщо перший аргумент є екземпляром будь-якого з типів у цій послідовності:

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

Іншими словами, isinstance() вже пропонує цю функцію нестандартно.

З isinstance()документації :

Якщо classinfo не є ні об'єктом класу, ні об'єктом типу, це може бути набір об'єктів класу або типу або може рекурсивно містити інші такі кортежі (інші типи послідовностей не приймаються).

Акцент мій; відзначити рекурсивний характер; (classinfo1, (classinfo2, classinfo3))також є дійсним варіантом.


Корисно, дякую!
— Яков Бресслер

11

Ви вже були досить близькі з назвою свого запитання. Ви можете використовувати anyі список:

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

Але заглянувши в документи isinstanceвиявляє:

Повертає true, якщо аргумент об'єкта є екземпляром аргументу classinfo або його (прямого, непрямого або віртуального) підкласу. Якщо об'єкт не є об'єктом даного типу, функція завжди повертає false. Якщо classinfo не є класом (об'єктом типу), це може бути набір об'єктів типу або може рекурсивно містити інші такі кортежі (інші типи послідовностей не приймаються). Якщо classinfo не є типом або кортежем типів і таких кортежів, виникає виняток TypeError.

Це означає, що кращий спосіб це зробити

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

2
Повторення isinstanceлише зі classinfoзмінами мені здається не дуже пітонічним.
— Макото

1
Спробуйте var.__class__. Це те, що ти хочеш? @Makoto: Я згоден. Зовсім не пітонічна!
— фламенко

@Makoto Yup. Але це було те, що Д. Адамс, напевно, міг легко знайти, шукаючи в документах "будь-який". Я розширив свою відповідь до кращої версії ... але, очевидно, Мартін Пітерс був швидшим ... ще раз.
— Мартін Тома

3
any()зі списком є ​​.. безглуздо. Використовуйте генератор виразу, якщо вам потрібно використовувати any(), тоді, принаймні, ви отримаєте перевагу від раннього виходу.
— Мартін Пітерс

Я думаю, що isinstanceз кортежем - це шлях. Я просто хотів згадати рішення, anyоскільки, здавалося б, саме те, про що він просить у назві.
— Мартін Тома

4

Це вирішить вашу проблему:

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

На основі документації існує безліч способів передачі значень типів isinstance.

Ви також можете заглянути в сладострасні, якщо намагаєтесь зробити більш складну перевірку, частина якої це лише частина.


isinstance () вже пропонує цю функціональність, передайте кортеж з усіма необхідними типами для перевірки як другий аргумент
— RFV

@ RFV5s Так .... ось що показує приклад, який я навів тут. Яке ваше заперечення?
— Натаніель Форд,

1

Як правило, ви не повинні використовувати isinstance, але те, що ви хочете зробити, можна досягти за допомогою будь-якої () вбудованої функції.

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

7
Це надмірне; isinstance()пропонує функціональність з коробки без використання any().
— Мартін Пітерс

@MartijnPieters Я не усвідомлював, що isinstance може приймати кілька типів, але я вважаю, що відповідь все-таки хороша, оскільки питання можна сприймати ширше як "Як мені перевірити, чи є будь-яке з повернених значень від певної функції з різними параметрами правда "
— Чад С.,

Чи слід вам користуватися чи ні, не має isinstance()значення.
— RFV

@ChadS. Я хотів би запитати вас, чому, на вашу думку, він не повинен використовувати isinstance()? Дякую.
— ідатура

Тому що python уникає перевірки типу. Це багато додаткового коду (і циклів процесора) з невеликою користю. Переважно набирати качок.
— Чад С.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.