python 是预分配和重新分配变量更好,还是检查变量是否存在并在之后创建它们更好?

fv2wmkja  于 2023-04-28  发布在  Python
关注(0)|答案(1)|浏览(143)

我有一个编程哲学问题,关于什么是“更好”或“更Python”的赋值变量的方法。

在变量可能不被函数赋值但必须在以后存在(至少作为占位符存在)的情况下,哪个选项更好?

1.预先将它们全部赋值,然后在函数中重新赋值一些
1.在函数结束时,只分配到之前未分配的那些
我将给予一个例子,并描述我的具体情况,但希望有人能回答一般的问题,而不仅仅是优化这个示例代码。

示例:

Image.merge('RGB', bands)需要来自image_normalization()Image.new()的三个输入图像(每种颜色一个),但我的一些数组中只有1-2种颜色。我可以(1)在开始时初始化所有三个图像,然后根据输入替换/调整它们的大小,或者(2)在最后检查丢失的颜色,只创建所需的占位符。

1.预分配和重新分配:

def image_merge(inputArray:np.ndarray, noOfColors:int) -> Image.Image:

    img0 = Image.new('L',(1,1),0)
    img1 = Image.new('L',(1,1),0)
    img2 = Image.new('L',(1,1),0)

    for colorNumber in range(noOfColors):
        globals()[f'img{colorNumber}'] = image_normalization(inputArray, colorNumber)
    
    if img1.size == 1: img1 = Image.new('L',img0.size,0)
    if img2.size == 1: img2 = Image.new('L',img0.size,0)

    imgMerge = Image.merge('RGB', (img0, img1, img2))
    return imgMerge

2.等到最后再创建:

def image_merge(inputArray:np.ndarray, noOfColors:int) -> Image.Image:

    for colorNumber in range(noOfColors):
        globals()[f'img{colorNumber}'] = image_normalization(inputArray, colorNumber)
    
    if 'img1' not in globals(): globals()['img1'] = Image.new('L',img0.size,0)
    if 'img2' not in globals(): globals()['img2'] = Image.new('L',img0.size,0)

    imgMerge = Image.merge('RGB', (img0, img1, img2))
    return imgMerge

另一个版本的“等待结束”将使用try块代替if语句,即。即:

try: img1
except: img1 = Image.new('L',img0.size,0)
try: img2
except: img2 = Image.new('L',img0.size,0)

更多上下文:

我使用Pillow模块从1-3个像素强度数组创建RGB图像。image_normalization函数从阵列创建单色图像,Image.merge()函数从3个单色图像创建RGB图像(每种颜色一个:红色、绿色和蓝色),所有的尺寸都相同。然而,我的一些输入数组只包含1-2种颜色的信息,因此我需要在合并之前用Image.new()创建1-2个占位符数组。

ctehm74n

ctehm74n1#

我认为这两个选项(如上所述)都不是特别的pythonic,一般来说,我会警告不要在globals()上操作变量赋值。这会使理解发生了什么变得更加困难,并允许引入一些奇怪的bug(例如,如果您的函数意外地被调用,而noColors的值要高得多,该怎么办?当你只显式地使用一个非常小的子集时,你可能会分配任意数量的内存)
这里有一个替代方案:

# Using your camelCase convention
def image_merge(inputArray:np.ndarray, noOfColors:int, requiredColors: int = 3) -> Image.Image:
    images = []

    for colorNumber in range(min(noOfColors, requiredColors)):
        images.append(image_normalization(inputArray, colorNumber))
    
    if len(images) == 0:
        # no colours specified- raise exception?
        raise Exception("yikes")

    while len(images) < requiredColors:
        images.append(Image.new('L', images[0].size, 0))

    imgMerge = Image.merge('RGB', tuple(*images))
    return imgMerge

在这种情况下,您可以避免使用任何“魔法”,并通过阅读代码非常清楚地了解实际发生了什么,以及如何以及为什么要创建默认情况。

相关问题