简体   繁体   中英

PyPDF2 Encrypting PDF with Python on Windows: AttributeError: 'tuple' object has no attribute 'write'

Edit to include full Code: Program basics -- Take CSV file of ID/EMAIL/PASSWORD, and create dictionary1. Create a dictionary2 of ID/File in a path.

Use Dictionary2 to lookup password in Dict1, apply encryption, and finally email using email in Dict1. I'm stuck at the encryption part at this point.

I've read some questions and google articles about needing to open the file, but I'm not sure how to open the "output" item...

Error:

Traceback (most recent call last):
  File "CommissionSecurity.py", line 54, in <module>
    output.write(outputStream)
  File "build\bdist.win-amd64\egg\PyPDF2\pdf.py", line 472, in write
AttributeError: 'tuple' object has no attribute 'write'

Code:

import os 
import re
import csv
import PyPDF2


# Create a dictionary with the csv values
EmailDict = dict()
with open('commissionrepemaillist.csv', 'r') as infile:
    reader = csv.reader(infile)
    for row in reader :
        REP = row[0]
        EMAIL = row[1]
        PASSWORD = row[2]
        EmailDict[REP] = EMAIL, PASSWORD

# create dictionary of IDs and Pdf Files
FileDict = dict()
path = "C:\\Apps\\CorVu\\DATA\\Reports\\AlliD\\Monthly Commission  Reports\\Output\\pdcom1"  
for FILE in os.listdir(path):
    split = re.split("[_.]", FILE)
    ID = split[1]
    FileDict[ID] = FILE

for ID in FileDict:
    # print REP
    # print ID # debug: REP always coming over 764 
    if ID in EmailDict : 
        #print FileDict[ID]
        path = "C:\\Apps\\CorVu\\DATA\\Reports\\AlliD\\Monthly Commission Reports\\Output\\pdcom1\\"
        file = open(os.path.join(path + FileDict[ID]), 'rb')
        output = PyPDF2.PdfFileWriter()
        input = PyPDF2.PdfFileReader(file)

        print ID, EmailDict[ID][1]  # returning the correct value for encryption
        output.encrypt(EmailDict[ID][1])
        outputStream = (file, "wb")
        output.write(outputStream)

        output.close()
        input.close()

    else : continue
outputStream = (file, "wb")

This just creates a tuple with a file and a string. The PDF writer write method doesn't know what to do with an arbitrary tuple, it expects a file-like object. You probably wanted to instead open that file for writing instead:

outputStream = open(file.name, "wb")

Now taking the name from an existing file object and reusing it is probably not the best way to do this. Generate the file path once then reuse that for opening the original file then use again for writing out to the PDF file you have processed.

Also your code would be improved by using the file context managers .

with open(file, "wb") as outputStream:
    output.write(outputStream)

This way your files will be closed at the end of the statement and your file resources will be handled properly. It also reduces the code maintenance cost because you don't need to pair open and close statements for the files as that is now done for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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