Pergunta

I am having some issues with a small program I have made that edits Pdfs using pyPdf. I am attempting to pass the last page of the pdf (self.lastpage) as a default parameter to a class method (pageoutput) When I do this I receive the following error:

Traceback (most recent call last):
  File "C:\Census\sf1.py", line 5, in <module>
    class PdfGet():
  File "C:\Census\sf1.py", line 35, in PdfGet
    def pageoutput(self,outfile,start_page=0,end_page=self.lastpage):
NameError: name 'self' is not defined 

If i simply specify a number as the end_page it works, yet it fails if I use an attribute. This error is a bet cryptic to me. It doesnt seem to be a problem with pypdf as I can print the lastpage of the pdf with no issues. I would greatly appreciate any insight as to what is going on!

Here is my code (I am using the 3.x compatbile version of pypdf if that matters):

from pyPdf import PdfFileWriter, PdfFileReader
import re
import time

class PdfGet():
    def __init__(self):
        self.initialize()

    def initialize(self):
        while True:
            raw_args = input('Welcome to PdfGet...\n***Please Enter Arugments (infile,outfile,start_page,end_page) OR type "quit" to exit***\n').strip() 
            if raw_args.lower() == 'quit':
                break
            print("Converting Pdf...")
            self.args = re.split(r',| ',raw_args)
            self.opener(*self.args[0:1])
            if len(self.args)== 4:
                self.pageoutput(*self.args[1:])
            elif len(self.args) == 3:
                self.pageoutput(*self.args[1:3])
            else:
                self.pageoutput(*self.args[1:2])
            print("Successfuly Converted!")
            nextiter = input('Convert Another PDF? (Type "yes" or "no")').lower()
            if nextiter == 'no':
                break

    def opener(self,infile):
        self.output = PdfFileWriter()
        self.pdf = PdfFileReader(open(infile, "rb"))
        self.pagenum = self.pdf.getNumPages()
        self.lastpage = self.pagenum+1
        print(self.lastpage)

    def pageoutput(self,outfile,start_page=0,end_page=self.lastpage):
        for i in range (int(start_page)-1,int(end_page)):
            self.output.addPage(self.pdf.getPage(i))    
        outputStream = open(outfile, "wb")
        self.output.write(outputStream)
        outputStream.close()

if __name__ == "__main__":
    PdfGet()
    time.sleep(5)
Foi útil?

Solução

You should rather pass it a default argument to None and then in the method do the assignment yourself.

def pageoutput(self, outfile, start_page=0, end_page=None):
    if end_page is None:
        end_page = self.lastpage

It is not possible to use self in the method declaration because at this stage self is not yet defined (method signatures are read when the module is loaded, and self is available at runtime when the method is called.)

Outras dicas

Default arguments are evaluated when the function is created, not when the function is executed, and they live in the namespace where the function is being defined, not in the namespace of the function itself.

This has the following consequences: 1. You can't reference other arguments of the function in a default value – the value of this argument doesn't exist yet. 2. You should be careful when using mutable values as default values – all calls to the function would receive the same mutable object.

So, if you want to access the other arguments (such as self) or to use a fresh mutable object when constructing the default value, you should use None as the default, and assign something different during the execution of the function.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top