Python 将多个变量初始化为相同的初始值

问题描述 投票:0回答:8

我已经解决了这些问题,

  1. Python 将多个变量分配给同一个值?列出行为
    关注元组,我想要的只是变量可以是字符串、整数或字典
  2. 同时声明多个变量的更优雅的方式
    问题有我想问的,但接受的答案很复杂

所以我想要实现的目标,

我声明变量如下,我想将这些声明减少到尽可能少的代码行。

details = None
product_base = None
product_identity = None
category_string = None
store_id = None
image_hash = None
image_link_mask = None
results = None
abort = False
data = {}

什么是最简单、易于维护的?

python variables variable-assignment
8个回答
79
投票

我同意其他答案,但想在这里解释一下重点。

None对象是单例对象。将 None 对象分配给变量多少次,会使用同一个对象。所以

x = None
y = None

等于

x = y = None

但是你不应该对 python 中的任何其他对象做同样的事情。例如,

x = {}  # each time a dict object is created
y = {}

不等于

x = y = {}  # same dict object assigned to x ,y. We should not do this.

36
投票

首先我建议你不要这样做。它不可读且不符合 Python 风格。但是,您可以使用以下命令减少行数:

details, product_base, product_identity, category_string, store_id, image_hash, image_link_mask, results = [None] * 8
abort = False
data = {}

17
投票
(
    details,
    producy_base,
    product_identity,
    category_string,
    store_id,
    image_hash,
    image_link_mask,
    results,
) = (None, None, None, None, None, None, None, None)

abort = False
data = {}

我就是这么做的。


7
投票

我使用了一个单行 lambda 函数来帮助我解决这个问题。

nones = lambda n: [None for _ in range(n)]
v, w, x, y, z = nones(5)

lambda 与此相同。

def nones(n):
    return [None for _ in range(n)]

2
投票

以前的答案的混合:

from copy import deepcopy

def default(number, value = None):
    if type(value) is dict or object:
        return [deepcopy(value) for _ in range(number)]
    else:
        return [value] * number
    
o, p, q, r, s = default(5)
t, u = default(2, false)
v, w, x = default(3, {})

class GPU:
  def __init__(self, m, p):
    self.model = m
    self.price = p
 
rtx_3080 = GPU("RTX 3080", 99999)

y, z = default(2, rtx_3080)

编辑

尝试通过更好地处理 pandas/numpy 类型的可变变量来优化深度复制调用。可能还漏掉了一些其他的。如果有人找到更好的方法来检查可变性,请随时分享。尽管如此,无论您的用例是什么,这都可能是过度设计的......

import builtins
from copy import deepcopy
from numbers import Number
from pandas import api, DataFrame

mutables = (dict, list, set, DataFrame)
immutables = (str, tuple, frozenset, Number)

def is_built_in_type(var):
    return type(var).__name__ in dir(builtins)

def is_mutable(var):
    return var is not None and (api.types.is_list_like(var) or isinstance(var, mutables) or not is_built_in_type(var))

def is_immutable(var):
    return var is None or isinstance(var, immutables)

def default(number, value=None):
    if is_mutable(value):
        return [deepcopy(value) for _ in range(number)]
    elif is_immutable(value):
        return [value] * number
    else:
        raise ValueError("Unexpected value type")

a, b, c, d, e = default(5)
f, g, h = default(3, False)
i, j = default(2, "False")
k, l, m, n = default(4, (3, 2, 1))
o, p = default(2, 3.14159265358979)
q, r, s = default(3, [1, 2, 3])
t, u = default(2, {})
v, w, x = default(3, DataFrame({'col1': [7, 13, 42, 73, 666], 'col2': [1, 0.6, 2, 1.4, 0.3]}))

class GPU:
    def __init__(self, m, p):
        self.model = m
        self.price = p

rtx_3080 = GPU("RTX 3080", 99999)

y, z = default(2, rtx_3080)

1
投票

在参加了@belgacea的答案下的讨论后,我想发布我认为最好的答案的变体:

import copy

def duplicate(value, n):
    return [copy.deepcopy(value) for _ in range(n)]

a, b, c = duplicate([0], 3)
o, p, q, r, s = duplicate(None, 5)
t, u = duplicate(False, 2)
v, w, x = duplicate({}, 3)
y, z = duplicate(MyClass(), 2)

在所有情况下,我们都通过

deepcopy()
保证可变对象不会在一起初始化的不同变量之间共享,这是要避免的重要问题。

但我已将代码简化为最简单的表达式,利用

deepcopy
已经经过很好的优化,可以在其输入不可变时执行浅复制。我已经用字符串和元组对此进行了测试,如果
x
是递归不可变的,例如
x = ((1,2),"foo")
,那么
x is copy.deepcopy(x)
返回 True,因此尝试避免在不可变的值上调用
deepcopy
没有任何好处。需要深拷贝。

我还更改了函数的签名和名称,我认为这样可以在使用它时生成更好的自记录代码。


0
投票

这样:

( var1, var2, var3, var3, var4,
var5, var6 ) = ( [None] * 6 )

如果由于多个变量和/或大名称而希望它成为多行,则括号很重要。另外,不要忘记将“无”放在方括号之间。


-2
投票

这并没有直接回答问题,但它是相关的——我使用空类的实例来对相似的属性进行分组,因此我不必通过列出所有属性来弄乱我的 init 方法。

class Empty:
    pass

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.w = Empty()          # widgets
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.w.entry = tk.Entry(self, bg="orange", fg="black", font=FONT)

SimpleNamespace 和空类定义有什么区别?

© www.soinside.com 2019 - 2024. All rights reserved.