如何接受文件或路径作为python中方法的参数

时间:2012-05-21 21:10:14

标签: python file python-3.x typechecking

我正在尝试编写一个接受已打开文件的方法

myFile = open("myFile.txt")
obj.writeTo(myFile)
myFile.close()

或带路径的字符串

obj.writeTo("myFile.txt")

该方法实现如下:

def writeTo(self, hessianFile):
    if isinstance(hessianFile,file):
        print("File type")
    elif isinstance(hessianFile,str):
        print("String type")
    else:
        pass

但这会引发错误

NameError: global name 'file' is not defined

为什么文件类型没有定义?不应该一直定义文件吗?如何纠正实现以正确地将文件路径作为有效参数类型

3 个答案:

答案 0 :(得分:4)

不要打字检查!这不是Pythonic。更好的选择是简单地选择更常见的结果,尝试按照你的方式工作,如果你得到异常,则不能使用其他方法:

def writeTo(self, hessianFile):
    try:
        with open(hessianFile, "w") as f:
            do_stuff(f)
    except TypeError:
        do_stuff(hessianFile)

或者,如果您认为自己更有可能在大多数情况下获得文件对象,那么就这样做:

def writeTo(self, hessianFile):
    try:
        do_stuff(f)
    except AttributeError:
        with open(hessianFile, "w") as f:
            do_stuff(f)

请注意我使用the with statement这是处理打开文件的最佳方式 - 它更具可读性,并且始终为您关闭文件,即使是异常也是如此。

原始代码失败的原因是file不是3.x中open()返回的对象的基类。

  

open()函数返回的文件对象的类型取决于   模式。当open()用于以文本模式打开文件时('w','r',   'wt','rt'等),它返回io.TextIOBase的子类   (特别是io.TextIOWrapper)。用于打开二进制文件时   具有缓冲的模式,返回的类是其子类   io.BufferedIOBase。确切的类别有所不同:在读取二进制模式中,它   返回一个io.BufferedReader;在写二进制和附加二进制模式,   它返回一个io.BufferedWriter,在读/写模式下,它返回一个   io.BufferedRandom。禁用缓冲时,原始流,a   返回io.RawIOBase的子类io.FileIO。 Source

所以你需要io.FileIO

答案 1 :(得分:2)

不要使用名称'file'(python中的内置对象)作为类文件对象的名称。

f = open("myFile.txt")
obj.writeTo(f)
f.close()

示例:

>>> filetype = lambda x: isinstance(x, file)
>>> file = open('t','w')
>>> filetype(file)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

>>> f = open('t','w')
>>> del file
>>> filetype(f)
True

答案 2 :(得分:1)

Python 3中没有file类型。它在Python 2中是内置,但它在Python 3中消失了。比较以下内容:

Python 2.7.1 [...]
>>> f = open('zz.bak', 'w')
>>> type(f)
<type 'file'>
>>> print f.__doc__
file(name[, mode[, buffering]]) -> file object

Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),
writing or appending.  The file will be created if it doesn't exist
when opened for writing or appending; it will be truncated when
opened for writing.  Add a 'b' to the mode for binary files.
Add a '+' to the mode to allow simultaneous reading and writing.
If the buffering argument is given, 0 means unbuffered, 1 means line
buffered, and larger numbers specify the buffer size.  The preferred way
to open a file is with the builtin open() function.
Add a 'U' to mode to open the file for input with universal newline
support.  Any line ending in the input file will be seen as a '\n'
in Python.  Also, a file so opened gains the attribute 'newlines';
the value for this attribute is one of None (no newline read yet),
'\r', '\n', '\r\n' or a tuple containing all the newline types seen.

'U' cannot be combined with 'w' or '+' mode.

在Python 3中...

Python 3.2.1 [...]
>>> f = open('xx', 'w')
>>> type(f)
<class '_io.TextIOWrapper'>
>>> print(f.__doc__)
Character and line based layer over a BufferedIOBase object, buffer.

encoding gives the name of the encoding that the stream will be
decoded or encoded with. It defaults to locale.getpreferredencoding.

errors determines the strictness of encoding and decoding (see the
codecs.register) and defaults to "strict".

newline can be None, '', '\n', '\r', or '\r\n'.  It controls the
handling of line endings. If it is None, universal newlines is
enabled.  With this enabled, on input, the lines endings '\n', '\r',
or '\r\n' are translated to '\n' before being returned to the
caller. Conversely, on output, '\n' is translated to the system
default line seperator, os.linesep. If newline is any other of its
legal values, that newline becomes the newline when the file is read
and it is returned untranslated. On output, '\n' is converted to the
newline.

If line_buffering is True, a call to flush is implied when a call to
write contains a newline character.