NameError: name 'self' is not defined when passing attribute as parameter to method
-
25-12-2020 - |
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)
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.