如何接受文件或路径作为python中方法的参数 [英] how to accept file or path as arguments to method in python

查看:516
本文介绍了如何接受文件或路径作为python中方法的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to write a method that will accept either an opened file

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

为什么未定义文件类型?不应该一直定义文件吗?应该如何纠正实现,以正确地将两个路径都视为有效的参数类型

why is file type not defined? Shouldn't file be defined all the time? How should the implementation be corrected to properly handel both path an file as valid argument types

推荐答案

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

Don't type check! It's not Pythonic. The core of duck typing is the idea that if it quacks like a duck, it is a duck. The behaviour you want is if it is file-like, it works, and if it is string-like, it works. This isn't just ideological - because this is the standard in Python, people will expect to be able to give you a file-like object and have it work. If you restrict it to only a specific file type, your code will be fragile and inflexible.

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

The simplest option is to simply pick the more common outcome, try to work as you would with that, and fail to the other method if you get an exception:

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

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

This might seem bad if you are used to other languages where "using exceptions for flow control" is considered bad, but that isn't the case in Python, where they are a core part of the language regularly used that way (every for loop ends with an exception!).

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

Or, if you think you are more likely to get a file object most of the time, do it the other way around:

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

请注意我对 with语句的使用这是处理打开文件的最佳方法-更具可读性,并且总是甚至在发生异常时也始终为您关闭文件.

Note my use of the with statement which is the best way of dealing with opening files - it's more readable, and also always closes the file for you, even on exceptions.

如果真的 发现必须进行键入检查(例如:即使操作失败,操作也非常昂贵,并且无法短路),则应检查字符串侧,因为它如果类似字符串的东西比类似文件的东西更容易计算.如果必须检查类似文件的内容,则应实现

If you really find you have to type check (e.g: the operation is extremely expensive even if it fails, with no way to short-circuit), you should check the string side, as it is easier to work out if something is string-like as opposed to file-like. If you have to check for something file-like, you should implement an abstract base class and look for the functionality you need, rather than actually type-checking.

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

The reason your original code failed is that file isn't the base class of objects returned by open() in 3.x.

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

The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper). When used to open a file in a binary mode with buffering, the returned class is a subclass of io.BufferedIOBase. The exact class varies: in read binary mode, it returns a io.BufferedReader; in write binary and append binary modes, it returns a io.BufferedWriter, and in read/write mode, it returns a io.BufferedRandom. When buffering is disabled, the raw stream, a subclass of io.RawIOBase, io.FileIO, is returned. Source

为此,您需要 io.FileIO .

So for that you want io.FileIO.

这篇关于如何接受文件或路径作为python中方法的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆