两次打开文件,但不知道如何修复

时间:2018-09-09 17:54:19

标签: python python-3.x

files = []

os.listdir("C:\\Users\\Name\\Attachments")
for filename in os.listdir(os.getcwd()):
    with open(filename) as f:
        files.append(f)

for file in files:
    with open(file, 'rb') as fp:
        img = MIMEImage(fp.read())
msg.attach(img)

运行此命令时,它会给我错误

TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper

我知道这是由于我两次打开文件导致的,但是我不确定如何解决此问题。任何帮助表示赞赏。谢谢

Stacktrace

Traceback (most recent call last):
File "c:\users\yic-hin\mu_code\email test2.py", line 21, in <module>
with open(file, 'rb') as fp:
TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper

1 个答案:

答案 0 :(得分:1)

您在这里有几个问题。

文件对象超出范围

您第一次在with块中的文件名上调用close()时使用的是context manager。上下文管理器管理资源的生命周期,并确保在离开该块时执行适当的整理操作。对于文件,上下文管理器安排自动调用该文件上的with open(filename) as f: files.append(f) 方法。

以下代码:

f = open(filename)
files.append(f)
f.close()
就此答案而言,

大约等于:

f

因此,将文件对象with附加到列表中并尝试在open外部 使用它。。该文件将被关闭,并且流上的任何后续操作将无法进行(docs)。

open的第一个参数应该是字符串, 1 不是是文件对象

1 ,或更准确地说,是类似路径的对象-参见下文

您的代码在遇到上述问题之前崩溃,因为您尝试将文件对象传递给open方法。这是不正确的。 file的第一个参数file在文档中的定义如下:

  

False是一个类似路径的对象,提供了要打开的文件的路径名(相对于当前工作目录的绝对路径或相对于当前工作目录的路径名)或要包装的文件的整数文件描述符。 (如果给出了文件描述符,则除非关闭closefd设置为str,否则当关闭返回的I / O对象时,它将关闭。)

类路径对象defined,因此:

  

代表文件系统路径的对象。类路径对象是表示路径的bytesos.PathLike对象,或者是实现open协议的对象。

传递给open的最简单的值是一个字符串,它表示计算机上文件的路径。您传递给_io.TextIOWrapper的文件对象的类型为open,它不是类似路径的对象,并且不能在对TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper 的调用中使用:

files = []

os.listdir("C:\\Users\\Name\\Attachments")
for filename in os.listdir(os.getcwd()):
    with open(filename, 'rb') as f:
        img = MIMEImage(f.read())

# I also assume you want to attach /every/ processed image, not
# just the last one. If so, you must ensure this is indented to
# the same level as the `with` block inside the `for` loop.
msg.attach(img)

正确方法

有几种方法可以解决此问题;最简单的方法是一次打开文件并避免双重循环,在您提供的示例中,这对您没有任何好处。例如,以下代码不应出现此问题:

Caused by: android.view.InflateException: Binary XML file line #11: Binary XML file line #54: Error inflating class fragment
     Caused by: android.view.InflateException: Binary XML file line #54: Error inflating class fragment
     Caused by: java.lang.NullPointerException
        at java.lang.VMClassLoader.findLoadedClass(Native Method)
        at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.support.v4.app.Fragment.isSupportFragmentClass(Fragment.java:499)
        at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3637)
        at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
        at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:338)
        at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:39)
        at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:67)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.parseInclude(LayoutInflater.java:995)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:859)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
        at com.example.lenovo.ridder.Home.onCreate(Home.java:28)
        at android.app.Activity.performCreate(Activity.java:7183)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)