繁体   English   中英

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

[英]how to accept file or path as arguments to method in python

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

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

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

不要输入检查! 这不是Pythonic。 鸭子打字的核心思想是,如果它像鸭子一样发出嘎嘎声,那就是鸭子。 您想要的行为是,如果它像文件一样 ,它可以工作,而如果它像字符串 ,则它可以工作。 这不仅是意识形态的-因为这是Python中的标准,所以人们希望能够为您提供类似文件的对象并使之正常工作。 如果将其限制为仅特定文件类型,则代码将脆弱且不灵活。

最简单的选择是简单地选择更常见的结果,尝试按此方式工作,如果遇到异常,则不尝试其他方法:

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

如果习惯于使用“使用异常进行流控制”的其他语言,那么这似乎很糟糕,但是在Python中却不是这种情况,因为它们是这种方式经常使用的语言的核心部分(每个for循环以一个异常结束!)。

或者,如果您认为大多数情况下更有可能获得文件对象,请采用另一种方法:

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

请注意我使用with语句 ,这是处理打开文件的最佳方法-更具可读性,并且即使有异常也总是为您关闭文件。

如果您确实发现必须键入check(例如:即使操作失败,操作也非常昂贵,并且无法短路),则应检查字符串端,因为如果字符串为-,则更容易确定-喜欢而不是喜欢文件。 如果您必须检查类似文件的内容,则应实现一个抽象基类并查找所需的功能,而不是实际进行类型检查。

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

open()函数返回的文件对象的类型取决于模式。 当使用open()以文本模式(“ w”,“ r”,“ wt”,“ rt”等)打开文件时,它将返回io.TextIOBase的子类(尤其是io.TextIOWrapper)。 当使用带缓冲的二进制模式打开文件时,返回的类是io.BufferedIOBase的子类。 确切的类有所不同:在读取二进制模式下,它返回io.BufferedReader; 在写二进制和追加二进制模式下,它返回io.BufferedWriter,在读/写模式下,它返回io.BufferedRandom。 禁用缓冲后,将返回原始流,即io.RawIOBase的子类io.FileIO。 资源

因此,您需要io.FileIO

不要将名称“ 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

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM