RHEL7.4 Python2.7环境下自定义pyqrcode类合并二维码到PDF报AttributeError错误
问题背景
- 运行环境:RHEL 7.4
- Python环境:2.7(受第三方服务器权限限制,无法升级更高版本)
- 开发目标:实现QR二维码生成,并将二维码嵌入到导出的PDF文档中
- 异常现象:将二维码生成、PDF导出两个功能拆分为独立脚本运行时功能正常,合并为同一脚本后直接报错
报错日志
[user@myserver scripts]$ python pdf_test3.py Traceback (most recent call last): File "pdf_test3.py", line 28, in <module> qcode = pyqrcode("http://www.weather.com","/cfg/test.png") File "pdf_test3.py", line 8, in __init__ qrCode = self.create(url) AttributeError: pyqrcode instance has no attribute 'create'
问题根因
- 命名冲突:自定义类
pyqrcode和导入的pyqrcode模块重名,直接覆盖了原模块的命名空间 - 方法调用逻辑错误:
pyqrcode.create()是模块级的工厂方法,不属于QRCode类的实例方法,在继承QRCode的子类中通过self.create()调用自然无法找到对应属性 - 父类初始化缺失:自定义的
PDF类继承FPDF时,没有在__init__中调用父类的初始化方法,且将页面元素绘制逻辑错误放在了类初始化阶段,此时PDF还没有加载页面,后续即使解决二维码报错也会出现PDF绘制失败的问题 - 路径权限问题:原代码将二维码保存到
/cfg/test.png的根目录路径下,普通用户没有写入权限,运行时还会触发PermissionError
修复方案
- 移除冗余的自定义二维码类,直接调用
pyqrcode模块原生的create()方法生成二维码实例 - 调整PDF类的结构,将二维码绘制、标题绘制逻辑从类初始化方法中移出,遵循FPDF的标准调用流程:先初始化PDF对象,添加页面后再绘制各类元素
- 调整文件输出路径为当前用户有权限写入的相对路径,避免触发权限报错
适配Python2.7的可运行代码
from fpdf import FPDF import pyqrcode # 1. 生成二维码,直接调用模块原生方法 qr = pyqrcode.create("http://www.weather.com") # 保存二维码为PNG,scale参数控制二维码尺寸 qr.png("test_qr.png", scale=3) # 2. 自定义PDF类,保留页脚逻辑 class PDF(FPDF): def footer(self): # 距底部1.5cm位置绘制页脚 self.set_y(-15) self.set_font('Arial', 'I', 8) self.cell(0, 10, 'Page ' + str(self.page_no()) + '/{nb}', 0, 0, 'C') # 3. 按FPDF标准流程生成PDF pdf = PDF() pdf.alias_nb_pages() pdf.add_page() pdf.set_font('Times', '', 12) # 绘制二维码(位置:距左侧200mm,距顶部1mm,尺寸20*20mm) pdf.image("test_qr.png", 200, 1, 20, 20) # 绘制标题 pdf.cell(30, 10, 'Title', 1, 1, 'C') # 循环写入正文内容 for i in range(1, 5): pdf.cell(0, 10, 'Hello World.' + str(i), 0, 1) # 导出PDF文件 pdf.output('test.pdf', 'F')
运行说明
执行脚本前先确认适配Python2.7版本的依赖已安装完整:pyqrcode、pypng(用于PNG格式导出)、fpdf
运行脚本后会在当前目录生成两个文件:test_qr.png(生成的二维码图)、test.pdf(嵌入二维码的最终PDF)
内容的提问来源于stack exchange,提问作者KevinH
相关产品推荐
相关产品推荐

