【问题标题】:Python - multiple instances on a loopPython - 循环上的多个实例
【发布时间】:2020-06-15 09:20:42
【问题描述】:

我有以下类来生成随机简单的 PDF。

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import letter
import random
import string
import os

BOOTH_NAME = [
        'Distrito', 'Sector', 'Residencia', 'Fraccionamiento',
        'Privado', 'Ciudad', 'Colonia', 'Departamentos',
        'Recinto', 'Barrio', 'Comuna', 'Vecindad'
    ]
BOOTH_CODE = list(string.ascii_uppercase)
ZONE_CODE = ['NORTE', 'OESTE', 'SUR', 'ESTE', 'SUROESTE', 'NOROESTE', 'SURESTE', 'NORESTE']
CONCEPT_NAME = ['COMPRA/VENTA', 'TESTIMONIO', 'ESCRITURAS']
WIDTH, HEIGHT = letter
DIR_NAME = '/Users/gmwill934/PycharmProjects/notarIA/pdfs/'

class PDF(object):
    def __init__(
            self,
            casilla=str(BOOTH_NAME[random.randint(0, len(BOOTH_NAME) - 1)]),
            clave_casilla=str(BOOTH_CODE[random.randint(0, len(BOOTH_CODE) - 1)]),
            zona=str(ZONE_CODE[random.randint(0, len(ZONE_CODE) - 1)]),
            concepto=str(CONCEPT_NAME[random.randint(0, len(CONCEPT_NAME) - 1)])
    ):
        self.casilla = casilla
        self.clave_casilla = clave_casilla
        self.zona = zona
        self.concepto = concepto
        self.name = '{} {} {}'.format(self.casilla, self.clave_casilla, self.zona)
        self.save_name = os.path.join(PDF.DIR_NAME, self.name+'.pdf')

    def create_pdf(self):
        pdf = Canvas(self.save_name, pagesize=letter)
        pdf.setTitle(self.name)
        pdf.grid([10, PDF.WIDTH - 10], [10, PDF.HEIGHT - 10])
        pdf.drawString(20, PDF.HEIGHT - 30, 'Numero de Casilla:')
        pdf.drawString(130, PDF.HEIGHT - 30, str(random.randint(1000, 9999)))
        pdf.drawString(20, PDF.HEIGHT - 50, 'Nombre de Casilla:')
        pdf.drawString(130, PDF.HEIGHT - 50, self.name)
        pdf.drawString(20, PDF.HEIGHT - 70, 'Numero de Votos:')
        pdf.drawString(130, PDF.HEIGHT - 70, str(random.randint(100000, 999999)))
        pdf.drawString(20, PDF.HEIGHT - 90, 'Concepto:')
        pdf.drawString(130, PDF.HEIGHT - 90, str(self.concepto))
        pdf.showPage()
        pdf.save()

基本上,create_pdf 方法使用随机值创建 PDF。

接下来我要做的是创建PDF class 的多个实例,以一次创建多个PDF。

from src.pdf import PDF
# instantiate PDF class
# create multiple instances
pdf = PDF()
for n in range(10):
    pdf.create_pdf()

我也试过这个。

from src.pdf import PDF
# instantiate PDF class
# create multiple instances
for n in range(10):
    pdf = PDF()
    pdf.create_pdf()

问题是它只创建了 1 个 PDF 文件,而我期待 10 个。它似乎在创建 1 个 PDF 后完成。

有人可以就此提出建议吗?我错过了什么吗?

【问题讨论】:

  • 循环肯定运行了 10 次(如果你只是在循环中打印 n 就可以看到这一点)。您的问题很可能在于 pdf 的名称每次都相同,因此您只需写入/覆盖相同的 pdf 10 次(对您来说显示为 1 个 pdf)。
  • pdf的名字是随机创建的,有多大几率可以和之前的名字一样?我还使用列表推导来创建多个实例,我可以看到在内存中创建了不同的对象,但它仍然只创建 1 个 pdf。
  • 你在什么操作系统上运行这个?您可以尝试在调用随机之前根据时间设置随机种子吗?我的猜测是,您会不断获得相同的第一个随机值超过 10 次。 stackoverflow.com/questions/33806022/…
  • mac os x, python3.而且我已经设置了 random.seed(42) 并且我仍然得到相同的结果。
  • 默认参数(使用random)在函数声明时计算一次,而不是在调用时计算。您可以设置默认参数None 并在函数体中检查它们。

标签: python python-3.x oop instance reportlab


【解决方案1】:

function(method)定义时评估的参数的默认值。
所以你的随机生成逻辑只运行一次。
你应该这样做:

    def __init__(
            self,
            casilla=None,
            ...
    ):
        self.casilla = (
            casilla if casilla is not None else
            str(BOOTH_NAME[random.randint(0, len(BOOTH_NAME) - 1)]))
        ...

参考:https://docs.python.org/3/reference/compound_stmts.html#function-definitions

默认参数值在函数定义执行时从左到右计算。这意味着表达式在定义函数时计算一次,并且相同的“预计算”值用于每个调用。当默认参数是可变对象(例如列表或字典)时,这一点尤其重要:如果函数修改了对象(例如,通过将项目附加到列表中),则默认值实际上已被修改。这通常不是预期的。解决这个问题的一种方法是使用 None 作为默认值,并在函数体中显式测试它,例如:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2019-06-15
    相关资源
    最近更新 更多