为什么在Python中继承对象,在不指定父对象的情况下更改__dict__的类型呢?

时间:2013-09-28 16:46:10

标签: python inheritance

我有一段简单的代码试图为Python中的file提供便利。

class File:
    def __init__(this, *args):
        this._file = file(*args)

    def __del__(this):
        this._file.close()

def createCallForwarder(method):
    return lambda obj,*args: method(obj._file, *args)

_dict = file.__dict__
for (k,v) in zip(_dict.keys(), _dict.values()):
    if not (k.startswith('__') and k.endswith('__')):
        if v.__class__.__name__ == 'method_descriptor':
            File.__dict__[k] = createCallForwarder(v)

# get the repr method
File.__repr__ = createCallForwarder(dict_proxy['__repr__'])

如果我将File更改为继承自object,则不会让我分配方法。

为什么会有所不同?

2 个答案:

答案 0 :(得分:4)

您根本不应直接访问__dict__

使用__getattr__ method代理对基础self._file对象的调用:

class File(object):
    def __init__(self, *args):
        self._file = open(*args)

    def __getattr__(self, name):
        return getattr(self._file, name)

我还将代码转换为最佳实践;使用self代替this并使用open()代替file()

对于新式对象(继承自object),请使用setattr()设置任意属性。但是,不需要使用呼叫转发器包装器。您可以采用self._file绑定方法,并直接在self上设置这些方法:

class File(object):
    def __init__(self, *args):
        self._file = open(*args)
        for name in dir(self._file):
            setattr(self, name, getattr(self._file, name))

如果您想要的只是一个在垃圾收集时自动关闭的文件对象,那么您就会遇到很多麻烦。 Python文件对象已经__del__处理程序,完全相同。它不是作为显式__del__函数公开的,而是C实现使用deallocation function在解除分配时调用close_the_file(f)

但是,最佳做法是使用with statement

将文件对象用作上下文管理器
with open(somefilename) as fileobj:
    # do all sorts with fileobj

# here, fileobj will have been closed automatically.

引用file.close() documentation

  

从Python 2.5开始,如果使用with语句,则可以避免必须显式调用此方法。例如,以下代码将在退出with块时自动关闭 f

from __future__ import with_statement # This isn't required in Python 2.6

with open("hello.txt") as f:
    for line in f:
        print line,

答案 1 :(得分:0)

  

我只是想让一个自我关闭的File对象

使用with statement,其中包括(除其他外)关闭文件:

with open('somefile.txt') as the_file:
   for line in the_file:
      # do something with line

# Once outside the with block, the file is automatically closed
print('somefile.txt is closed here')