如何创建可变变量?

发布于 2024-08-03 22:52:41 字数 393 浏览 10 评论 0原文

我知道其他一些语言,例如 PHP,支持“变量变量名”的概念 - 也就是说,字符串的内容可以用作变量名的一部分。

我听说这通常是一个坏主意,但我认为它可以解决我在 Python 代码中遇到的一些问题。

在Python中可以做这样的事情吗?会出现什么问题?


如果您只是想按名称查找现有变量,请参阅如何选择变量按(字符串)名称?。但是,首先考虑是否可以按照本问题中的建议重新组织代码以避免这种需要。

I know that some other languages, such as PHP, support a concept of "variable variable names" - that is, the contents of a string can be used as part of a variable name.

I heard that this is a bad idea in general, but I think it would solve some problems I have in my Python code.

Is it possible to do something like this in Python? What can go wrong?


If you are just trying to look up an existing variable by its name, see How can I select a variable by (string) name?. However, first consider whether you can reorganize the code to avoid that need, following the advice in this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

梦里泪两行 2024-08-10 22:52:42

我正在回答问题 如何获取字符串中给定名称的变量的值?
它作为副本关闭,并带有指向此问题的链接。 (编者注:它现在作为 How can我通过(字符串)名称选择一个变量?


如果所讨论的变量是对象的一部分(例如类的一部分),那么一些有用的函数可以准确地实现这些功能:hasattrgetattrsetattr

例如,您可以:

class Variables(object):
    def __init__(self):
        self.foo = "initial_variable"

    def create_new_var(self, name, value):
        setattr(self, name, value)

    def get_var(self, name):
        if hasattr(self, name):
            return getattr(self, name)
        else:
            raise "Class does not have a variable named: " + name

然后您可以这样做:

>>> v = Variables()
>>> v.get_var("foo")
'initial_variable'
>>> v.create_new_var(v.foo, "is actually not initial")
>>> v.initial_variable
'is actually not initial'

I'm answering the question How to get the value of a variable given its name in a string?
which is closed as a duplicate with a link to this question. (Editor's note: It is now closed as a duplicate of How can I select a variable by (string) name?)


If the variables in question are part of an object (part of a class for example) then some useful functions to achieve exactly that are hasattr, getattr, and setattr.

So for example you can have:

class Variables(object):
    def __init__(self):
        self.foo = "initial_variable"

    def create_new_var(self, name, value):
        setattr(self, name, value)

    def get_var(self, name):
        if hasattr(self, name):
            return getattr(self, name)
        else:
            raise "Class does not have a variable named: " + name

Then you can do:

>>> v = Variables()
>>> v.get_var("foo")
'initial_variable'
>>> v.create_new_var(v.foo, "is actually not initial")
>>> v.initial_variable
'is actually not initial'
無處可尋 2024-08-10 22:52:42

我已经在 python 3.7.3 中尝试过,您可以使用 globals() 或 vars()

>>> food #Error
>>> milkshake #Error
>>> food="bread"
>>> drink="milkshake"
>>> globals()[food] = "strawberry flavor"
>>> vars()[drink] = "chocolate flavor"
>>> bread
'strawberry flavor'
>>> milkshake
'chocolate flavor'
>>> globals()[drink]
'chocolate flavor'
>>> vars()[food]
'strawberry flavor'

参考:
https:// /www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936

I have tried both in python 3.7.3, you can use either globals() or vars()

>>> food #Error
>>> milkshake #Error
>>> food="bread"
>>> drink="milkshake"
>>> globals()[food] = "strawberry flavor"
>>> vars()[drink] = "chocolate flavor"
>>> bread
'strawberry flavor'
>>> milkshake
'chocolate flavor'
>>> globals()[drink]
'chocolate flavor'
>>> vars()[food]
'strawberry flavor'

Reference:
https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936

柒七 2024-08-10 22:52:42

共识是为此使用字典 - 请参阅其他答案。对于大多数情况来说,这是一个好主意,但是,由此产生了很多方面:

  • 您自己负责这个字典,包括(字典中变量的)垃圾收集等。
  • 变量变量要么没有局部性,要么没有全局性,如果你想重命名变量名,这取决于字典的全局性
  • ,你必须手动完成,
  • 但是,你更灵活,例如
    • 您可以决定覆盖现有变量或...
    • ...选择实现const变量
    • 针对不同类型的覆盖引发异常
    • 等等

也就是说,我已经实现了 变量管理器-类提供了上述一些想法。它适用于 python 2 和 3。

您可以使用 class 像这样:

from variableVariablesManager import VariableVariablesManager

myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])

# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
    myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
    print("not allowed")
except AttributeError as e:
    pass

# rename a variable
myVars.renameVariable('myconst', 'myconstOther')

# preserve locality
def testLocalVar():
    myVars = VariableVariablesManager()
    myVars['test'] = 13
    print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])

# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
    myVars = VariableVariablesManager()
    print("inside function myVars['globalVar']:", myVars['globalVar'])
    myVars['globalVar'] = 13
    print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])

如果您希望只允许覆盖相同类型的变量:

myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)

The consensus is to use a dictionary for this - see the other answers. This is a good idea for most cases, however, there are many aspects arising from this:

  • you'll yourself be responsible for this dictionary, including garbage collection (of in-dict variables) etc.
  • there's either no locality or globality for variable variables, it depends on the globality of the dictionary
  • if you want to rename a variable name, you'll have to do it manually
  • however, you are much more flexible, e.g.
    • you can decide to overwrite existing variables or ...
    • ... choose to implement const variables
    • to raise an exception on overwriting for different types
    • etc.

That said, I've implemented a variable variables manager-class which provides some of the above ideas. It works for python 2 and 3.

You'd use the class like this:

from variableVariablesManager import VariableVariablesManager

myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])

# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
    myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
    print("not allowed")
except AttributeError as e:
    pass

# rename a variable
myVars.renameVariable('myconst', 'myconstOther')

# preserve locality
def testLocalVar():
    myVars = VariableVariablesManager()
    myVars['test'] = 13
    print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])

# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
    myVars = VariableVariablesManager()
    print("inside function myVars['globalVar']:", myVars['globalVar'])
    myVars['globalVar'] = 13
    print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])

If you wish to allow overwriting of variables with the same type only:

myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)
沫雨熙 2024-08-10 22:52:42

任何变量集也可以包含在一个类中。
“变量”变量可以在运行时通过 __dict__ 属性直接访问内置字典来添加到类实例中。

以下代码定义了 Variables 类,该类在构造期间将变量(在本例中为属性)添加到其实例。变量名称取自指定列表(例如,可以由程序代码生成):

# some list of variable names
L = ['a', 'b', 'c']

class Variables:
    def __init__(self, L):
        for item in L:
            self.__dict__[item] = 100

v = Variables(L)
print(v.a, v.b, v.c)
#will produce 100 100 100

Any set of variables can also be wrapped up in a class.
"Variable" variables may be added to the class instance during runtime by directly accessing the built-in dictionary through __dict__ attribute.

The following code defines Variables class, which adds variables (in this case attributes) to its instance during the construction. Variable names are taken from a specified list (which, for example, could have been generated by program code):

# some list of variable names
L = ['a', 'b', 'c']

class Variables:
    def __init__(self, L):
        for item in L:
            self.__dict__[item] = 100

v = Variables(L)
print(v.a, v.b, v.c)
#will produce 100 100 100
深者入戏 2024-08-10 22:52:42

应该说风险很大...
但你可以使用 exec():

a = 'b=5'
exec(a)
c = b*2
print (c)

结果:
10

It should be extremely risky...
but you can use exec():

a = 'b=5'
exec(a)
c = b*2
print (c)

Result:
10

浸婚纱 2024-08-10 22:52:42

setattr()方法设置指定对象的指定属性的值。

语法如下 -

setattr(object, name, value)
Example –

setattr(self,id,123)

相当于 self.id = 123

正如您可能已经观察到的,setattr() 期望将一个对象与要生成的值一起传递/修改一个新属性。

我们可以使用 setattr() 和解决方法,以便能够在模块中使用。这是如何——

import sys
x = "pikachu"
value = 46
thismodule = sys.modules[__name__]
setattr(thismodule, x, value)
print(pikachu)

The setattr() method sets the value of the specified attribute of the specified object.

Syntax goes like this –

setattr(object, name, value)
Example –

setattr(self,id,123)

which is equivalent to self.id = 123

As you might have observed, setattr() expects an object to be passed along with the value to generate/modify a new attribute.

We can use setattr() with a workaround to be able to use within modules. Here’ how –

import sys
x = "pikachu"
value = 46
thismodule = sys.modules[__name__]
setattr(thismodule, x, value)
print(pikachu)
南烟 2024-08-10 22:52:42

TL;DR:考虑使用 eval()

我找到此页面是因为我希望使用 python 字符串函数进行一些简单的模板处理(缺少完整的模板引擎) )。我正在寻找如何设置局部变量,这就是我到达这里的方式。

我的问题从一个简单的模板开始:

Hello, {name}

我填充这个模板的方式是这样的:

def populate(template,variables):
    return template.format(**variables)

所以这会起作用:

values = {
  'name' : 'Stack Overflow' 
}
my_template = "Hello, {name}"
print( populate( my_template , values ) )

# output
Hello, Stack Overflow

但后来事情进展得很快。我尝试了一个新模板,我只想要第一个单词:

现在我的模板是这样的: "Hello, {name.split()[0]}" 并且此代码出现错误。

values['name'] = "Stack Overflow"
my_template = "Hello, {name.split()[0]}"
print( populate( my_template , values ) 
# output (well, stderr)
AttributeError: 'str' object has no attribute 'split()'. Did you mean: 'split'?

然后我了解到格式功能并没有按照我想要的方式工作。您不能向其传递任意代码。你需要传递它格式化的东西。所以我尝试了不同的解决方案。我编写了 populate 来使用 eval 和 f 字符串而不是 format。 f 字符串(与格式不同)允许在大括号插值中使用 python 代码。所以像这样的 f 字符串 `f"Hello, {name.split()[0]}" 确实有效。让我们看看这个小部分的代码(这样你就不必离开这篇文章来找出 f 字符串):

name = "Stack Overflow"
print(f"Hello, {name.split()[0]}")
# Output:
Hello, Stack

现在我只需要使用 f 字符串。所以我使用了eval。我的新填充是这样的:

def populate(template,variables):
    return eval(f'f"{template}"')

但是当我再次运行该程序时,我收到此错误:

NameError: name 'name' is not defined

我应该指出 f 字符串能够使用范围内的任何全局或局部变量填充字符串。为了解决我的问题,我可以将模板更改为 "Hello, {variables['name']}" 因为 variables 肯定在范围内。这是非常糟糕的方法,因为现在模板编写者必须了解 variables 字典。相反,我想让模板作者可以使用 variables 字典中可用的每个键,就像我之前使用 format(**variables) 所做的那样。

为了解决我的问题,我想根据传递给 populate() 函数的 variables 字典的内容来设置局部变量。

我尝试了这个:

locals() = variables

但这不起作用:

    locals() = variables
    ^^^^^^^^
SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='?

然后我尝试了这个,这起作用了:

def populate(template,variables):
    for k,v in variables.items():
      locals()[k] = v
    return eval(f'f"{template}"')


values = {
  'name' : 'Stack Overflow'
}
my_template = "Hello, {name.split()[0]}"
print( populate( my_template , values ) )

所以第一个要点是您可以在函数中创建局部变量(或就此而言的全局变量)通过在 locals() 字典中设置键值对。

对于 eval 来说,第二个和第三个参数允许您传入局部变量和全局变量,因此您可以将 populate 函数简化为:

def populate(template,variables):
    return eval(f'f"{template}"',variables)

以上是我使用 eval 的方式 进行 f 字符串填充(或简单的模板评估)。但是eval也可以用来提供可变变量。

TL;DR: Consider using eval()

I found this page because I was looking to do some simple template processing with python string functions (short of including a full blown template engine). I was searching for how to set local variables, and that's how I got here.

My problem began with a simple template:

Hello, {name}

The way I populated this template was this way:

def populate(template,variables):
    return template.format(**variables)

And so this would work:

values = {
  'name' : 'Stack Overflow' 
}
my_template = "Hello, {name}"
print( populate( my_template , values ) )

# output
Hello, Stack Overflow

But then things went south fast. I tried a new template where I only wanted the first word:

Now my template was this: "Hello, {name.split()[0]}" and this code got an error.

values['name'] = "Stack Overflow"
my_template = "Hello, {name.split()[0]}"
print( populate( my_template , values ) 
# output (well, stderr)
AttributeError: 'str' object has no attribute 'split()'. Did you mean: 'split'?

And then I learned that the format function doesn't work the way I want it. You can't pass arbitrary code to it. You need to pass it formatting stuff. And so I tried a different solution. I coded populate to use eval and an f-string instead of format. An f-string (unlike format) allows for python code in the curly brace interpolation. So an f-string like this `f"Hello, {name.split()[0]}" does work. Let's just see the code for this small part (so you don't have to leave this post to figure out f-string):

name = "Stack Overflow"
print(f"Hello, {name.split()[0]}")
# Output:
Hello, Stack

Now I just had to use an f-string. So I used eval. My new populate is this:

def populate(template,variables):
    return eval(f'f"{template}"')

But when I ran the program again, I got this error:

NameError: name 'name' is not defined

I should point out that an f-string is able to populate the string with any global or local variable in scope. To fix my issue, I could change my template to "Hello, {variables['name']}" since variables is definitely in scope. This is really bad approach because now the template writer has to know about a the variables dictionary. Rather, I want to make every key available in the variables dictionary available to the template author, as I had before with format(**variables).

To solve my problem, I wanted to set local variables based on the content of the variables dictionary passed to the populate() function.

I tried this:

locals() = variables

And that didn't work:

    locals() = variables
    ^^^^^^^^
SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='?

And then I tried this and this worked:

def populate(template,variables):
    for k,v in variables.items():
      locals()[k] = v
    return eval(f'f"{template}"')


values = {
  'name' : 'Stack Overflow'
}
my_template = "Hello, {name.split()[0]}"
print( populate( my_template , values ) )

And so the first take away is that you can create local variables in a function (or globals for that matter) by setting a key value pair in the locals() dictionary.

In the case of eval, the second and third parameters allow you to pass in local and global variables, and so you could simplify the populate function to just this:

def populate(template,variables):
    return eval(f'f"{template}"',variables)

The above is how I used eval to do f-string population (or simplistic template evaluation). But eval can also be used to provide variable variables.

余生共白头 2024-08-10 22:52:41

您可以使用 字典 来完成此操作。字典是键和值的存储。

>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'x': 1, 'y': 2, 'z': 3}
>>> dct["y"]
2

可以使用可变键名来达到可变变量的效果,而且不会有安全风险。

>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'

对于您正在考虑执行诸如

var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...

list 之类的操作的情况,可能更合适比一个字典。列表表示对象的有序序列,具有整数索引:

lst = ['foo', 'bar', 'baz']
print(lst[1])           # prints bar, because indices start at 0
lst.append('potatoes')  # lst is now ['foo', 'bar', 'baz', 'potatoes']

对于有序序列,列表比具有整数键的字典更方便,因为列表支持按索引顺序迭代,切片追加以及其他需要使用字典进行笨拙密钥管理的操作。

You can use dictionaries to accomplish this. Dictionaries are stores of keys and values.

>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'x': 1, 'y': 2, 'z': 3}
>>> dct["y"]
2

You can use variable key names to achieve the effect of variable variables without the security risk.

>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'

For cases where you're thinking of doing something like

var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...

a list may be more appropriate than a dict. A list represents an ordered sequence of objects, with integer indices:

lst = ['foo', 'bar', 'baz']
print(lst[1])           # prints bar, because indices start at 0
lst.append('potatoes')  # lst is now ['foo', 'bar', 'baz', 'potatoes']

For ordered sequences, lists are more convenient than dicts with integer keys, because lists support iteration in index order, slicing, append, and other operations that would require awkward key management with a dict.

暗藏城府 2024-08-10 22:52:41

使用内置的 getattr 函数获取按名称指定对象的属性。根据需要修改名称。

obj.spam = 'eggs'
name = 'spam'
getattr(obj, name)  # returns 'eggs'

Use the built-in getattr function to get an attribute on an object by name. Modify the name as needed.

obj.spam = 'eggs'
name = 'spam'
getattr(obj, name)  # returns 'eggs'
相思碎 2024-08-10 22:52:41

这不是一个好主意。如果您要访问全局变量,可以使用 globals()< /a>.

>>> a = 10
>>> globals()['a']
10

如果要访问本地范围内的变量,可以使用 locals()< /code>,但不能为返回的字典赋值。

更好的解决方案是使用getattr或将变量存储在字典中,然后按名称访问它们。

It's not a good idea. If you are accessing a global variable you can use globals().

>>> a = 10
>>> globals()['a']
10

If you want to access a variable in the local scope you can use locals(), but you cannot assign values to the returned dict.

A better solution is to use getattr or store your variables in a dictionary and then access them by name.

云裳 2024-08-10 22:52:41

新编码员有时会编写这样的代码:

my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...

然后,编码员会留下一堆命名变量,编码工作量为 O(m * n),其中 m 是命名变量的数量,n 是需要访问(包括创建)这组变量的次数。更精明的初学者观察到每一行中的唯一区别是根据规则更改的数字,并决定使用循环。然而,他们陷入了如何动态创建这些变量名称的困境,并且可能会尝试这样的事情:

for i in range(10):
    my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)

他们很快发现这不起作用。

如果程序需要任意变量“名称”,则字典是最佳选择,如其他答案中所述。但是,如果您只是尝试创建许多变量并且不介意用整数序列引用它们,那么您可能正在寻找列表。如果您的数据是同质的,例如每日温度读数、每周测验分数或图形小部件网格,则尤其如此。

可以按如下方式组装:

my_calculator.buttons = []
for i in range(10):
    my_calculator.buttons.append(tkinter.Button(root, text=i))

list 也可以通过推导式在一行中创建:

my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]

任一情况的结果都是填充的 list,其中第一个元素可通过以下方式访问: my_calculator.buttons[0],下一个是 my_calculator.buttons[1],依此类推。 “基本”变量名称成为列表的名称,并且使用变化的标识符来访问它。

最后,不要忘记其他数据结构,例如 set - 这类似于字典,只不过每个“名称”没有附加值。如果您只需要一“袋”物品,这可能是一个不错的选择。而不是这样的:

keyword_1 = 'apple'
keyword_2 = 'banana'

if query == keyword_1 or query == keyword_2:
    print('Match.')

您将拥有这样的:

keywords = {'apple', 'banana'}
if query in keywords:
    print('Match.')

使用 list 表示一系列相似的对象,使用 set 表示任意顺序的对象包,或者使用 >dict 用于一包具有关联值的名称。

New coders sometimes write code like this:

my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...

The coder is then left with a pile of named variables, with a coding effort of O(m * n), where m is the number of named variables and n is the number of times that group of variables needs to be accessed (including creation). The more astute beginner observes that the only difference in each of those lines is a number that changes based on a rule, and decides to use a loop. However, they get stuck on how to dynamically create those variable names, and may try something like this:

for i in range(10):
    my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)

They soon find that this does not work.

If the program requires arbitrary variable "names," a dictionary is the best choice, as explained in other answers. However, if you're simply trying to create many variables and you don't mind referring to them with a sequence of integers, you're probably looking for a list. This is particularly true if your data are homogeneous, such as daily temperature readings, weekly quiz scores, or a grid of graphical widgets.

This can be assembled as follows:

my_calculator.buttons = []
for i in range(10):
    my_calculator.buttons.append(tkinter.Button(root, text=i))

This list can also be created in one line with a comprehension:

my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]

The result in either case is a populated list, with the first element accessed with my_calculator.buttons[0], the next with my_calculator.buttons[1], and so on. The "base" variable name becomes the name of the list and the varying identifier is used to access it.

Finally, don't forget other data structures, such as the set - this is similar to a dictionary, except that each "name" doesn't have a value attached to it. If you simply need a "bag" of objects, this can be a great choice. Instead of something like this:

keyword_1 = 'apple'
keyword_2 = 'banana'

if query == keyword_1 or query == keyword_2:
    print('Match.')

You will have this:

keywords = {'apple', 'banana'}
if query in keywords:
    print('Match.')

Use a list for a sequence of similar objects, a set for an arbitrarily-ordered bag of objects, or a dict for a bag of names with associated values.

べ繥欢鉨o。 2024-08-10 22:52:41

每当您想使用可变变量时,最好使用字典。 不必

$foo = "bar"
$foo = "baz"

因此,您

mydict = {}
foo = "bar"
mydict[foo] = "baz"

编写这样的代码,这样您就不会意外地覆盖以前存在的变量(这是安全方面的),并且您可以拥有不同的“命名空间”。

Whenever you want to use variable variables, it's probably better to use a dictionary. So instead of writing

$foo = "bar"
$foo = "baz"

you write

mydict = {}
foo = "bar"
mydict[foo] = "baz"

This way you won't accidentally overwrite previously existing variables (which is the security aspect) and you can have different "namespaces".

你不是我要的菜∠ 2024-08-10 22:52:41

使用 globals() (免责声明:这是一种不好的做法,但这是对您的问题最直接的答案,请使用已接受答案中的其他数据结构)。

实际上,您可以动态地将变量分配给全局范围,例如,如果您想要在全局范围内访问 10 个变量 i_1, i_2 ... i_10

for i in range(10):
    globals()['i_{}'.format(i)] = 'a'

这会将“a”分配给所有这 10 个变量,当然您也可以动态更改该值。现在可以像其他全局声明的变量一样访问所有这些变量:

>>> i_5
'a'

Use globals() (disclaimer: this is a bad practice, but is the most straightforward answer to your question, please use other data structure as in the accepted answer).

You can actually assign variables to global scope dynamically, for instance, if you want 10 variables that can be accessed on a global scope i_1, i_2 ... i_10:

for i in range(10):
    globals()['i_{}'.format(i)] = 'a'

This will assign 'a' to all of these 10 variables, of course you can change the value dynamically as well. All of these variables can be accessed now like other globally declared variable:

>>> i_5
'a'
喜爱皱眉﹌ 2024-08-10 22:52:41

除了字典之外,您还可以使用 namedtuple 来自集合模块,这使得访问更容易。

例如:

# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])

# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
v = Variables(34, 45)
print(v.first, v.second)

Instead of a dictionary you can also use namedtuple from the collections module, which makes access easier.

For example:

# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])

# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
v = Variables(34, 45)
print(v.first, v.second)
一抹苦笑 2024-08-10 22:52:41

SimpleNamespace 类可用于创建使用 setattr 或子类 SimpleNamespace 创建新属性,并创建您自己的函数来添加新属性名称(变量)。

from types import SimpleNamespace

variables = {"b":"B","c":"C"}
a = SimpleNamespace(**variables)
setattr(a,"g","G")
a.g = "G+"
something = a.a

The SimpleNamespace class could be used to create new attributes with setattr, or subclass SimpleNamespace and create your own function to add new attribute names (variables).

from types import SimpleNamespace

variables = {"b":"B","c":"C"}
a = SimpleNamespace(**variables)
setattr(a,"g","G")
a.g = "G+"
something = a.a
我不是你的备胎 2024-08-10 22:52:41

如果您不想使用任何对象,您仍然可以在当前模块中使用 setattr()

import sys
current_module = module = sys.modules[__name__]  # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15)  # 15 is the value you assign to the var
print(variable_name)  # >>> 15, created from a string

If you don't want to use any object, you can still use setattr() inside your current module:

import sys
current_module = module = sys.modules[__name__]  # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15)  # 15 is the value you assign to the var
print(variable_name)  # >>> 15, created from a string
找个人就嫁了吧 2024-08-10 22:52:41

Python 中的变量

"""
<?php
$a = 'hello';
$e = 'wow'
?>
<?php
$a = 'world';
?>
<?php
echo "$a ${$a}\n";
echo "$a ${$a[1]}\n";
?>
<?php
echo "$a $hello";
?>
"""

a = 'hello'  #<?php $a = 'hello'; ?>
e = 'wow'   #<?php $e = 'wow'; ?>
vars()[a] = 'world' #<?php $a = 'world'; ?>
print(a, vars()[a]) #<?php echo "$a ${$a}\n"; ?>
print(a, vars()[vars()['a'][1]]) #<?php echo "$a ${$a[1]}\n"; ?>
print(a, hello) #<?php echo "$a $hello"; ?>

输出:

hello world
hello wow
hello world

使用 globals()、locals() 或 vars() 将产生相同的结果

#<?php $a = 'hello'; ?>
#<?php $e = 'wow'; ?>
#<?php $a = 'world'; ?>
#<?php echo "$a ${$a}\n"; ?>
#<?php echo "$a ${$a[1]}\n"; ?>
#<?php echo "$a $hello"; ?>

print('locals():\n')
a = 'hello'
e = 'wow'
locals()[a] = 'world'
print(a, locals()[a])
print(a, locals()[locals()['a'][1]])
print(a, hello)

print('\n\nglobals():\n')
a = 'hello'
e = 'wow'
globals()[a] = 'world'
print(a, globals()[a])
print(a, globals()[globals()['a'][1]])
print(a, hello)

输出:

locals():

hello world
hello wow
hello world


globals():

hello world
hello wow
hello world

奖励(从字符串创建变量)

# Python 2.7.16 (default, Jul 13 2019, 16:01:51)
# [GCC 8.3.0] on linux2

创建变量并解包元组:

g = globals()
listB = []
for i in range(10):
    g["num%s" % i] = i ** 10
    listB.append("num{0}".format(i))

def printNum():
    print "Printing num0 to num9:"
    for i in range(10):
        print "num%s = " % i, 
        print g["num%s" % i]

printNum()

listA = []
for i in range(10):
    listA.append(i)

listA = tuple(listA)
print listA, '"Tuple to unpack"'

listB = str(str(listB).strip("[]").replace("'", "") + " = listA")

print listB

exec listB

printNum()

输出:

Printing num0 to num9:
num0 =  0
num1 =  1
num2 =  1024
num3 =  59049
num4 =  1048576
num5 =  9765625
num6 =  60466176
num7 =  282475249
num8 =  1073741824
num9 =  3486784401
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) "Tuple to unpack"
num0, num1, num2, num3, num4, num5, num6, num7, num8, num9 = listA
Printing num0 to num9:
num0 =  0
num1 =  1
num2 =  2
num3 =  3
num4 =  4
num5 =  5
num6 =  6
num7 =  7
num8 =  8
num9 =  9

Variable variables in Python

"""
<?php
$a = 'hello';
$e = 'wow'
?>
<?php
$a = 'world';
?>
<?php
echo "$a ${$a}\n";
echo "$a ${$a[1]}\n";
?>
<?php
echo "$a $hello";
?>
"""

a = 'hello'  #<?php $a = 'hello'; ?>
e = 'wow'   #<?php $e = 'wow'; ?>
vars()[a] = 'world' #<?php $a = 'world'; ?>
print(a, vars()[a]) #<?php echo "$a ${$a}\n"; ?>
print(a, vars()[vars()['a'][1]]) #<?php echo "$a ${$a[1]}\n"; ?>
print(a, hello) #<?php echo "$a $hello"; ?>

Output:

hello world
hello wow
hello world

Using globals(), locals(), or vars() will produce the same results

#<?php $a = 'hello'; ?>
#<?php $e = 'wow'; ?>
#<?php $a = 'world'; ?>
#<?php echo "$a ${$a}\n"; ?>
#<?php echo "$a ${$a[1]}\n"; ?>
#<?php echo "$a $hello"; ?>

print('locals():\n')
a = 'hello'
e = 'wow'
locals()[a] = 'world'
print(a, locals()[a])
print(a, locals()[locals()['a'][1]])
print(a, hello)

print('\n\nglobals():\n')
a = 'hello'
e = 'wow'
globals()[a] = 'world'
print(a, globals()[a])
print(a, globals()[globals()['a'][1]])
print(a, hello)

Output:

locals():

hello world
hello wow
hello world


globals():

hello world
hello wow
hello world

Bonus (creating variables from strings)

# Python 2.7.16 (default, Jul 13 2019, 16:01:51)
# [GCC 8.3.0] on linux2

Creating variables and unpacking tuple:

g = globals()
listB = []
for i in range(10):
    g["num%s" % i] = i ** 10
    listB.append("num{0}".format(i))

def printNum():
    print "Printing num0 to num9:"
    for i in range(10):
        print "num%s = " % i, 
        print g["num%s" % i]

printNum()

listA = []
for i in range(10):
    listA.append(i)

listA = tuple(listA)
print listA, '"Tuple to unpack"'

listB = str(str(listB).strip("[]").replace("'", "") + " = listA")

print listB

exec listB

printNum()

Output:

Printing num0 to num9:
num0 =  0
num1 =  1
num2 =  1024
num3 =  59049
num4 =  1048576
num5 =  9765625
num6 =  60466176
num7 =  282475249
num8 =  1073741824
num9 =  3486784401
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) "Tuple to unpack"
num0, num1, num2, num3, num4, num5, num6, num7, num8, num9 = listA
Printing num0 to num9:
num0 =  0
num1 =  1
num2 =  2
num3 =  3
num4 =  4
num5 =  5
num6 =  6
num7 =  7
num8 =  8
num9 =  9
心的位置 2024-08-10 22:52:41

您必须使用 globals() 内置方法 实现该行为:

def var_of_var(k, v):
    globals()[k] = v

print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print(variable_name) # 123

some_name = 'variable_name2'
var_of_var(some_name, 456)
print(variable_name2) # 456

You have to use globals() built in method to achieve that behaviour:

def var_of_var(k, v):
    globals()[k] = v

print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print(variable_name) # 123

some_name = 'variable_name2'
var_of_var(some_name, 456)
print(variable_name2) # 456
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文