我已经解决了这些问题,
- Python 将多个变量分配给同一个值?列出行为
关注元组,我想要的只是变量可以是字符串、整数或字典- 同时声明多个变量的更优雅的方式
问题有我想问的,但接受的答案很复杂
所以我想要实现的目标,
我声明变量如下,我想将这些声明减少到尽可能少的代码行。
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 = {}
什么是最简单、易于维护的?
我同意其他答案,但想在这里解释一下重点。
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.
首先我建议你不要这样做。它不可读且不符合 Python 风格。但是,您可以使用以下命令减少行数:
details, product_base, product_identity, category_string, store_id, image_hash, image_link_mask, results = [None] * 8
abort = False
data = {}
(
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 = {}
我就是这么做的。
我使用了一个单行 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)]
以前的答案的混合:
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)
在参加了@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
没有任何好处。需要深拷贝。
我还更改了函数的签名和名称,我认为这样可以在使用它时生成更好的自记录代码。
这样:
( var1, var2, var3, var3, var4,
var5, var6 ) = ( [None] * 6 )
如果由于多个变量和/或大名称而希望它成为多行,则括号很重要。另外,不要忘记将“无”放在方括号之间。
这并没有直接回答问题,但它是相关的——我使用空类的实例来对相似的属性进行分组,因此我不必通过列出所有属性来弄乱我的 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)