2014-09-22 4 views
0

Мне нужно обрабатывать ZIP-файл со специализированным содержанием и, таким образом, хотят, чтобы создать оболочку, так что я могу использовать что-то вродеСоздать файл оболочку, которая может быть открыта

with open(MySpecialFile('/path/to/file.zip', 'rb')) as msf: 
    <snip> 

Я уже знаю, как реализовать __enter__ и __exit__, но я не могу найти документацию о том, как я могу сделать объект открытым. Я попытался реализовать функцию __open__ в надежде, что python применит метод open() таким образом. К сожалению, это, кажется, не так:

>>> class Foo(): 
...  def __open__(self): 
...   print('Opened!') 
... 
>>> with open(Foo()) as f: 
...  print('yay') 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: invalid file: <__main__.Foo object at 0x7f93b630ab00> 

Что такое правильный способ создать пользовательский объект, который может быть открыт с помощью open()?

ответ

2

Нет __open__ способ. Вместо этого вы должны создать что-то, что реализует file API. Простой класс будет выполнять до тех пор, пока он реализует все необходимые методы.

Тогда вы можете сказать:

with openMySpecialFile('/path/to/file.zip', 'rb') as msf: 
    ... 

где openMySpecialFile() является функцией фабрики, которая строит в экземпляре «что-то» выше и возвращает его.

+0

Так я полагаю, что нет никакого способа, чтобы использовать встроенный в открытом() в моем случае обертку непосредственно? –

+0

@RichardNeumann: Нет, это не имеет смысла. –

2

Или просто обернуть open:

class Foo(object): 
    def __init__(self, fpath, mode): 
     self.f = fpath 
     self.mode = mode 
    def __enter__(self): 
     print 'context begun' 
     self.file = open(self.f, self.mode) 
     return self.file 
    def __exit__(self, exc_type, exc_val, exc_tb): 
     print 'closing:', exc_type, exc_val, exc_tb 
     self.file.close() 
    def __str__(self): 
     return self.f 
with Foo('file.spc', 'rb') as f: 
    print f.read() 

>>> 
context begun 
filecontentsfilecontentsfilecontentsfilecontents 


closing: None None None 
>>> 
Смежные вопросы