关于继承:为什么从python中的对象继承,在不指定父对象时更改它们的类型?

Why does inherting from object in Python, change they type of the __dict__ when not specifying a parent does not?

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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继承,它就不允许我指定方法。

为什么不同?


您根本不应该直接访问__dict__

使用__getattr__方法来代理对基础self._file对象的调用:

1
2
3
4
5
6
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上:

1
2
3
4
5
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函数,当deallocation时调用close_the_file(f)

然而,最佳实践是使用文件对象作为上下文管理器,使用with语句:

1
2
3
4
with open(somefilename) as fileobj:
    # do all sorts with fileobj

# here, fileobj will have been closed automatically.

引用file.close()号文件:

As of Python 2.5, you can avoid having to call this method explicitly if you use the with statement. For example, the following code will automatically close f when the with block is exited:

1
2
3
4
5
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,


I was just trying to get a File object that closes itself

使用with statement,它将(除其他外)为您关闭文件:

1
2
3
4
5
6
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')