【问题标题】:NameError: name 'self' is not defined when passing attribute as parameter to methodNameError:将属性作为参数传递给方法时未定义名称“self”
【发布时间】:2011-08-13 14:06:01
【问题描述】:

我编写的一个使用 pyPdf 编辑 Pdfs 的小程序遇到了一些问题。我试图将 pdf 的最后一页 (self.lastpage) 作为默认参数传递给类方法 (pageoutput) 当我这样做时收到以下错误:

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 

如果我只是指定一个数字作为 end_page 它可以工作,但如果我使用属性它会失败。这个错误对我来说是一个神秘的赌注。 pypdf 似乎没有问题,因为我可以毫无问题地打印 pdf 的最后一页。我将不胜感激任何关于正在发生的事情的见解!

这是我的代码(如果重要的话,我使用的是 pypdf 的 3.x 兼容版本):

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)

【问题讨论】:

    标签: attributes python-3.x parameter-passing self pypdf


    【解决方案1】:

    您应该将默认参数传递给None,然后在方法中自己进行分配。

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

    在方法声明中不能使用self,因为在这个阶段self还没有定义(加载模块时读取方法签名,调用方法时self在运行时可用。)

    【讨论】:

    • 感谢修复!我应该更详细地搜索,因为显然我的错误很常见,我认为我过去曾使用 self.sth 作为默认参数,所以我从没想过这是问题所在。
    • 如果您认为是这种情况,请考虑将其标记为答案 :)
    【解决方案2】:

    默认参数是在创建函数时计算的,而不是在执行函数时,它们位于定义函数的命名空间中,而不是函数本身的命名空间中。

    这会产生以下后果: 1. 你不能在默认值中引用函数的其他参数——这个参数的值还不存在。 2. 使用可变值作为默认值时应该小心——所有对函数的调用都会收到相同的可变对象。

    因此,如果您想在构造默认值时访问其他参数(例如 self)或使用新的可变对象,则应使用 None 作为默认值,并在执行期间分配不同的东西功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      相关资源
      最近更新 更多