Для версій 3.1+ одне з наступного:
isinstance(something, io.TextIOBase)
isinstance(something, io.BufferedIOBase)
isinstance(something, io.RawIOBase)
isinstance(something, io.IOBase)
Для 2.x "файлоподібний об'єкт" - занадто розмита річ, щоб перевіряти, але документація щодо будь-яких функцій, з якими ви маєте справу, сподіваємось, розповість вам, що їм насправді потрібно; якщо ні, прочитайте код.
Як вказують інші відповіді, перше, що потрібно запитати, це те, що саме ви перевіряєте. Зазвичай EAFP є достатнім і більш ідіоматичним.
Словник каже «файл-подібний об'єкт» є синонімом «файлового об'єкта», який в кінцевому рахунку означає , що це екземпляр одного з трьох абстрактних базових класів , визначених у в io
модулі , які самі по собі всі підкласи IOBase
. Отже, спосіб перевірки - саме такий, як показано вище.
(Однак перевірка IOBase
не надто корисна. Чи можете ви уявити випадок, коли вам потрібно відрізнити фактичний файл, схожий на read(size)
якусь функцію з одним аргументом, названу read
не файлоподібно, без необхідності також розрізняти текстові файли та необроблені двійкові файли? Отже, насправді ви майже завжди хочете перевірити, наприклад, "це об'єкт текстового файлу", а не "є файлоподібний об'єкт".)
Для 2.x, хоча io
модуль існує з 2.6+, вбудовані файлові об'єкти не є екземплярами io
класів, а також жоден з файлоподібних об'єктів у stdlib, а також більшість сторонніх файлоподібних об'єктів, які ви швидше за все зіткнеться. Не було офіційного визначення того, що означає "файлоподібний об'єкт"; це просто "щось на зразок вбудованого об'єкта файлу ", а різні функції означають різні речі під "подобається". Такі функції повинні документувати, що вони означають; якщо вони цього не роблять, вам слід поглянути на код.
Однак найпоширенішими значеннями є "має read(size)
", "має read()
" або "це ітерація рядків", але деякі старі бібліотеки можуть очікувати readline
замість одного з них, деякі бібліотеки люблять close()
файли, які ви їм надаєте, деякі очікують, що якщо fileno
присутній, тоді доступна інша функціональність тощо. І так само для write(buf)
(хоча варіантів у цьому напрямку набагато менше).
why
як щодо операторів подобається__add__
,__lshift__
або__or__
в призначених для користувача класах? (об'єкт файлу та API: docs.python.org/glossary.html#term-file-object )