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.