标签归档:variables

如何在Python的同一行上打印变量和字符串?

问题:如何在Python的同一行上打印变量和字符串?

我正在使用python算出如果一个孩子每7秒出生一次,那么5年内将有多少个孩子出生。问题出在我的最后一行。当我在文本的任何一侧打印文本时,如何使它工作?

这是我的代码:

currentPop = 312032486
oneYear = 365
hours = 24
minutes = 60
seconds = 60

# seconds in a single day
secondsInDay = hours * minutes * seconds

# seconds in a year
secondsInYear = secondsInDay * oneYear

fiveYears = secondsInYear * 5

#Seconds in 5 years
print fiveYears

# fiveYears in seconds, divided by 7 seconds
births = fiveYears // 7

print "If there was a birth every 7 seconds, there would be: " births "births"

I am using python to work out how many children would be born in 5 years if a child was born every 7 seconds. The problem is on my last line. How do I get a variable to work when I’m printing text either side of it?

Here is my code:

currentPop = 312032486
oneYear = 365
hours = 24
minutes = 60
seconds = 60

# seconds in a single day
secondsInDay = hours * minutes * seconds

# seconds in a year
secondsInYear = secondsInDay * oneYear

fiveYears = secondsInYear * 5

#Seconds in 5 years
print fiveYears

# fiveYears in seconds, divided by 7 seconds
births = fiveYears // 7

print "If there was a birth every 7 seconds, there would be: " births "births"

回答 0

使用,分隔字符串和变量,同时打印:

print "If there was a birth every 7 seconds, there would be: ",births,"births"

, 在print语句中将项目分隔一个空格:

>>> print "foo","bar","spam"
foo bar spam

或更好地使用字符串格式

print "If there was a birth every 7 seconds, there would be: {} births".format(births)

字符串格式化功能强大得多,它还允许您执行其他一些操作,例如:填充,填充,对齐,宽度,设置精度等

>>> print "{:d} {:03d} {:>20f}".format(1,2,1.1)
1 002             1.100000
  ^^^
  0's padded to 2

演示:

>>> births = 4
>>> print "If there was a birth every 7 seconds, there would be: ",births,"births"
If there was a birth every 7 seconds, there would be:  4 births

#formatting
>>> print "If there was a birth every 7 seconds, there would be: {} births".format(births)
If there was a birth every 7 seconds, there would be: 4 births

Use , to separate strings and variables while printing:

print("If there was a birth every 7 seconds, there would be: ", births, "births")

, in print function separates the items by a single space:

>>> print("foo", "bar", "spam")
foo bar spam

or better use string formatting:

print("If there was a birth every 7 seconds, there would be: {} births".format(births))

String formatting is much more powerful and allows you to do some other things as well, like padding, fill, alignment, width, set precision, etc.

>>> print("{:d} {:03d} {:>20f}".format(1, 2, 1.1))
1 002             1.100000
  ^^^
  0's padded to 2

Demo:

>>> births = 4
>>> print("If there was a birth every 7 seconds, there would be: ", births, "births")
If there was a birth every 7 seconds, there would be:  4 births

# formatting
>>> print("If there was a birth every 7 seconds, there would be: {} births".format(births))
If there was a birth every 7 seconds, there would be: 4 births

回答 1

还有两个

第一个

 >>>births = str(5)
 >>>print "there are " + births + " births."
 there are 5 births.

添加字符串时,它们会串联在一起。

第二个

同样format,字符串的(Python 2.6和更高版本)方法可能是标准方法:

>>> births = str(5)
>>>
>>> print "there are {} births.".format(births)
there are 5 births.

format方法也可以与列表一起使用

>>> format_list = ['five','three']
>>> print "there are {} births and {} deaths".format(*format_list) #unpack the list
there are five births and three deaths

或字典

>>> format_dictionary = {'births': 'five', 'deaths': 'three'}
>>> print "there are {births} births, and {deaths} deaths".format(**format_dictionary) #yup, unpack the dictionary
there are five births, and three deaths

Two more

The First one

>>> births = str(5)
>>> print("there are " + births + " births.")
there are 5 births.

When adding strings, they concatenate.

The Second One

Also the format (Python 2.6 and newer) method of strings is probably the standard way:

>>> births = str(5)
>>>
>>> print("there are {} births.".format(births))
there are 5 births.

This format method can be used with lists as well

>>> format_list = ['five', 'three']
>>> # * unpacks the list:
>>> print("there are {} births and {} deaths".format(*format_list))  
there are five births and three deaths

or dictionaries

>>> format_dictionary = {'births': 'five', 'deaths': 'three'}
>>> # ** unpacks the dictionary
>>> print("there are {births} births, and {deaths} deaths".format(**format_dictionary))
there are five births, and three deaths

回答 2

Python是一种非常通用的语言。您可以通过不同的方法打印变量。我列出了以下4种方法。您可以根据需要使用它们。

例:

a=1
b='ball'

方法1:

print('I have %d %s' %(a,b))

方法2:

print('I have',a,b)

方法3:

print('I have {} {}'.format(a,b))

方法4:

print('I have ' + str(a) +' ' +b)

方法5:

  print( f'I have {a} {b}')

输出为:

I have 1 ball

Python is a very versatile language. You may print variables by different methods. I have listed below five methods. You may use them according to your convenience.

Example:

a = 1
b = 'ball'

Method 1:

print('I have %d %s' % (a, b))

Method 2:

print('I have', a, b)

Method 3:

print('I have {} {}'.format(a, b))

Method 4:

print('I have ' + str(a) + ' ' + b)

Method 5:

print(f'I have {a} {b}')

The output would be:

I have 1 ball

回答 3

如果要使用python 3,它非常简单:

print("If there was a birth every 7 second, there would be %d births." % (births))

If you want to work with python 3, it’s very simple:

print("If there was a birth every 7 second, there would be %d births." % (births))

回答 4

从python 3.6开始,您可以使用文字字符串插值。

births = 5.25487
>>> print(f'If there was a birth every 7 seconds, there would be: {births:.2f} births')
If there was a birth every 7 seconds, there would be: 5.25 births

As of python 3.6 you can use Literal String Interpolation.

births = 5.25487
>>> print(f'If there was a birth every 7 seconds, there would be: {births:.2f} births')
If there was a birth every 7 seconds, there would be: 5.25 births

回答 5

您可以使用f-string.format()方法

使用f弦

print(f'If there was a birth every 7 seconds, there would be: {births} births')

使用.format()

print("If there was a birth every 7 seconds, there would be: {births} births".format(births=births))

You can either use the f-string or .format() methods

Using f-string

print(f'If there was a birth every 7 seconds, there would be: {births} births')

Using .format()

print("If there was a birth every 7 seconds, there would be: {births} births".format(births=births))

回答 6

您可以使用格式字符串:

print "There are %d births" % (births,)

或在这种简单情况下:

print "There are ", births, "births"

You can either use a formatstring:

print "There are %d births" % (births,)

or in this simple case:

print "There are ", births, "births"

回答 7

如果您使用的是python 3.6或最新版本,则f-string是最佳和简便的选择

print(f"{your_varaible_name}")

If you are using python 3.6 or latest, f-string is the best and easy one

print(f"{your_varaible_name}")

回答 8

您将首先创建一个变量:例如:D =1。然后执行此操作,但是将字符串替换为所需的任何内容:

D = 1
print("Here is a number!:",D)

You would first make a variable: for example: D = 1. Then Do This but replace the string with whatever you want:

D = 1
print("Here is a number!:",D)

回答 9

在当前的python版本上,您必须使用括号,如下所示:

print ("If there was a birth every 7 seconds", X)

On a current python version you have to use parenthesis, like so :

print ("If there was a birth every 7 seconds", X)

回答 10

使用字符串格式

print("If there was a birth every 7 seconds, there would be: {} births".format(births))
 # Will replace "{}" with births

如果您在进行玩具项目,请使用:

print('If there was a birth every 7 seconds, there would be:' births'births) 

要么

print('If there was a birth every 7 seconds, there would be: %d births' %(births))
# Will replace %d with births

use String formatting

print("If there was a birth every 7 seconds, there would be: {} births".format(births))
 # Will replace "{}" with births

if you doing a toy project use:

print('If there was a birth every 7 seconds, there would be:' births'births) 

or

print('If there was a birth every 7 seconds, there would be: %d births' %(births))
# Will replace %d with births

回答 11

您可以使用字符串格式来执行此操作:

print "If there was a birth every 7 seconds, there would be: %d births" % births

或者您可以提供print多个参数,它将自动用空格分隔它们:

print "If there was a birth every 7 seconds, there would be:", births, "births"

You can use string formatting to do this:

print "If there was a birth every 7 seconds, there would be: %d births" % births

or you can give print multiple arguments, and it will automatically separate them by a space:

print "If there was a birth every 7 seconds, there would be:", births, "births"

回答 12

我将您的脚本复制并粘贴到.py文件中。我使用Python 2.7.10原样运行它,并收到了相同的语法错误。我还在Python 3.5中尝试了该脚本,并收到以下输出:

File "print_strings_on_same_line.py", line 16
print fiveYears
              ^
SyntaxError: Missing parentheses in call to 'print'

然后,我修改了最后一行,其中打印了出生人数,如下所示:

currentPop = 312032486
oneYear = 365
hours = 24
minutes = 60
seconds = 60

# seconds in a single day
secondsInDay = hours * minutes * seconds

# seconds in a year
secondsInYear = secondsInDay * oneYear

fiveYears = secondsInYear * 5

#Seconds in 5 years
print fiveYears

# fiveYears in seconds, divided by 7 seconds
births = fiveYears // 7

print "If there was a birth every 7 seconds, there would be: " + str(births) + " births"

输出为(Python 2.7.10):

157680000
If there was a birth every 7 seconds, there would be: 22525714 births

我希望这有帮助。

I copied and pasted your script into a .py file. I ran it as-is with Python 2.7.10 and received the same syntax error. I also tried the script in Python 3.5 and received the following output:

File "print_strings_on_same_line.py", line 16
print fiveYears
              ^
SyntaxError: Missing parentheses in call to 'print'

Then, I modified the last line where it prints the number of births as follows:

currentPop = 312032486
oneYear = 365
hours = 24
minutes = 60
seconds = 60

# seconds in a single day
secondsInDay = hours * minutes * seconds

# seconds in a year
secondsInYear = secondsInDay * oneYear

fiveYears = secondsInYear * 5

#Seconds in 5 years
print fiveYears

# fiveYears in seconds, divided by 7 seconds
births = fiveYears // 7

print "If there was a birth every 7 seconds, there would be: " + str(births) + " births"

The output was (Python 2.7.10):

157680000
If there was a birth every 7 seconds, there would be: 22525714 births

I hope this helps.


回答 13

只需在之间使用,(逗号)。

请参阅以下代码以获得更好的理解:

# Weight converter pounds to kg

weight_lbs = input("Enter your weight in pounds: ")

weight_kg = 0.45 * int(weight_lbs)

print("You are ", weight_kg, " kg")

Just use , (comma) in between.

See this code for better understanding:

# Weight converter pounds to kg

weight_lbs = input("Enter your weight in pounds: ")

weight_kg = 0.45 * int(weight_lbs)

print("You are ", weight_kg, " kg")

回答 14

稍有不同:使用Python 3并在同一行中打印几个变量:

print("~~Create new DB:",argv[5],"; with user:",argv[3],"; and Password:",argv[4]," ~~")

Slightly different: Using Python 3 and print several variables in the same line:

print("~~Create new DB:",argv[5],"; with user:",argv[3],"; and Password:",argv[4]," ~~")

回答 15

PYTHON 3

最好使用格式选项

user_name=input("Enter your name : )

points = 10

print ("Hello, {} your point is {} : ".format(user_name,points)

或将输入声明为字符串并使用

user_name=str(input("Enter your name : ))

points = 10

print("Hello, "+user_name+" your point is " +str(points))

PYTHON 3

Better to use the format option

user_name=input("Enter your name : )

points = 10

print ("Hello, {} your point is {} : ".format(user_name,points)

or declare the input as string and use

user_name=str(input("Enter your name : ))

points = 10

print("Hello, "+user_name+" your point is " +str(points))

回答 16

如果在字符串和变量之间使用逗号,如下所示:

print "If there was a birth every 7 seconds, there would be: ", births, "births"

If you use a comma inbetween the strings and the variable, like this:

print "If there was a birth every 7 seconds, there would be: ", births, "births"

从另一个文件导入变量?

问题:从另一个文件导入变量?

如何将变量从一个文件导入到另一个文件?

示例:file1具有变量x1以及x2如何将其传递给file2

如何将所有变量从一个导入到另一个?

How can I import variables from one file to another?

example: file1 has the variables x1 and x2 how to pass them to file2?

How can I import all of the variables from one to another?


回答 0

from file1 import *  

将导入file1中的所有对象和方法

from file1 import *  

will import all objects and methods in file1


回答 1

导入file1内部file2

要从文件1导入所有变量而不泛洪文件2的命名空间,请使用:

import file1

#now use file1.x1, file2.x2, ... to access those variables

要将所有变量从file1导入到file2的命名空间(不推荐):

from file1 import *
#now use x1, x2..

文档

虽然from module import *在模块级别使用是有效的,但通常不是一个好主意。首先,它失去了Python否则具有的重要属性-您可以知道每个顶级名称在您喜欢的编辑器中通过简单的“搜索”功能定义的位置。如果某些模块增加了其他功能或类,将来还会给自己带来麻烦。

Import file1 inside file2:

To import all variables from file1 without flooding file2’s namespace, use:

import file1

#now use file1.x1, file2.x2, ... to access those variables

To import all variables from file1 to file2’s namespace( not recommended):

from file1 import *
#now use x1, x2..

From the docs:

While it is valid to use from module import * at module level it is usually a bad idea. For one, this loses an important property Python otherwise has — you can know where each toplevel name is defined by a simple “search” function in your favourite editor. You also open yourself to trouble in the future, if some module grows additional functions or classes.


回答 2

最好显式导入x1x2

from file1 import x1, x2

这样可以避免file1在中工作时与变量和函数发生不必要的命名空间冲突file2

但是,如果您确实需要,可以导入所有变量:

from file1 import * 

Best to import x1 and x2 explicitly:

from file1 import x1, x2

This allows you to avoid unnecessary namespace conflicts with variables and functions from file1 while working in file2.

But if you really want, you can import all the variables:

from file1 import * 

回答 3

实际上,使用以下命令导入变量并不完全相同:

from file1 import x1
print(x1)

import file1
print(file1.x1)

在导入时,x1和file1.x1的值完全相同,但它们不是相同的变量。例如,在file1中调用一个修改x1的函数,然后尝试从主文件中打印该变量:您将看不到修改后的值。

Actually this is not really the same to import a variable with:

from file1 import x1
print(x1)

and

import file1
print(file1.x1)

Altough at import time x1 and file1.x1 have the same value, they are not the same variables. For instance, call a function in file1 that modifies x1 and then try to print the variable from the main file: you will not see the modified value.


回答 4

马克的回答是正确的。实际上,您可以打印变量的内存地址,print(hex(id(libvar))并且可以看到地址是不同的。

# mylib.py
libvar = None
def lib_method():
    global libvar
    print(hex(id(libvar)))

# myapp.py
from mylib import libvar, lib_method
import mylib

lib_method()
print(hex(id(libvar)))
print(hex(id(mylib.libvar)))

Marc response is correct. Actually, you can print the memory address for the variables print(hex(id(libvar)) and you can see the addresses are different.

# mylib.py
libvar = None
def lib_method():
    global libvar
    print(hex(id(libvar)))

# myapp.py
from mylib import libvar, lib_method
import mylib

lib_method()
print(hex(id(libvar)))
print(hex(id(mylib.libvar)))

回答 5

script1.py

title="Hello world"

script2.py是我们使用script1变量的地方

方法1:

import script1
print(script1.title)

方法2:

from script1 import title
print(title)

script1.py

title="Hello world"

script2.py is where we using script1 variable

Method 1:

import script1
print(script1.title)

Method 2:

from script1 import title
print(title)

回答 6

Python您可以访问的其他文件的内容像,就好像它们
是某种库,比起像Java或任何OOP语言基础等语言,这是真的很酷;

这使得可以访问文件的内容或将其导入以对其进行处理或对其进行任何处理;这就是为什么Python高度首选数据科学和机器学习等语言的主要原因;

这是 project structure 这个

我从.env file哪里访问API links秘密密钥和秘密密钥所在的位置。

总体结构:

from <File-Name> import *

In Python you can access the contents of other files like as if they
are some kind of a library, compared to other languages like java or any oop base languages , This is really cool ;

This makes accessing the contents of the file or import it to to process it or to do anything with it ; And that is the Main reason why Python is highly preferred Language for Data Science and Machine Learning etc. ;

And this is the picture of project structure This

Where I am accessing variables from .env file where the API links and Secret keys reside .

General Structure:

from <File-Name> import *

回答 7

first.py:

a=5

second.py:

import first
print(first.a)

结果将是5。

first.py:

a=5

second.py:

import first
print(first.a)

The result will be 5.


什么是无值?

问题:什么是无值?

我一直在研究Python,并且阅读了一章描述了它的None价值,但不幸的是,这本书在某些方面并不十分清楚。我认为,如果我在那分享我的问题,我会找到答案。

我想知道None价值什么,您将其用于什么?

而且,我没有得到本书的这一部分:

将值None赋给变量是将其重置为其原始的空状态的一种方法。

那是什么意思?

答案很棒,尽管由于我对计算机世界的了解不足(我还没有了解类,对象等),所以我对大多数答案都不了解。这句话是什么意思?

将值None赋给变量是将其重置为其原始的空状态的一种方法。

最后:

最后,我从寻找不同的答案中得到了答案。我必须感谢所有抽出宝贵时间来帮助我的人(尤其是Martijn Pieters和DSM),我希望我可以选择所有答案作为最佳答案,但是选择仅限于一个。所有的答案都很好。

I have been studying Python, and I read a chapter which describes the None value, but unfortunately this book isn’t very clear at some points. I thought that I would find the answer to my question, if I share it there.

I want to know what the None value is and what do you use it for?

And also, I don’t get this part of the book:

Assigning a value of None to a variable is one way to reset it to its original, empty state.

What does that mean?

The answers were great, although I didn’t understand most of answers due to my low knowledge of the computer world (I haven’t learned about classes, objects, etc.). What does this sentence mean?

Assigning a value of None to a variable is one way to reset it to its original, empty state.

Final:

Finally I’ve got my answer from looking to different answers. I must appreciate all the people who put their times to help me (especially Martijn Pieters and DSM), and I wish that I could choose all answers as the best, but the selection is limited to one. All of the answers were great.


回答 0

Martijn的答案解释了NonePython中的内容,并正确指出该书具有误导性。由于Python程序员通常不会说

将值None赋给变量是将其重置为其原始的空状态的一种方法。

很难以一种有意义的方式来解释布里格斯的意思,并解释为什么这里没有人对此感到满意。一个类推可能会有所帮助:

在Python中,变量名称就像贴在对象上的标签。每个标签上都有一个唯一的名称,并且一次只能在一个对象上,但是如果需要,您可以在同一对象上放置多个标签。当你写

F = "fork"

您将标签“ F”放在字符串对象上"fork"。如果你再写

F = None

您将标签移动到None对象。

Briggs想让您想象的是,您没有贴纸"F",但已经F贴纸上了None,您所做的就是其从None移到"fork"。因此F = None,如果我们决定将其None视为,则在键入时,您会将其“重置为原始的空状态” empty state

我可以看到他的意思,但这是一种不好的观察方式。如果启动Python并输入print(F),则会看到

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

NameError意味着Python无法识别这个名字F因为没有这样的标签。如果Briggs是正确的并且F = None重置F为原始状态,那么它应该现在在那里,并且我们应该看到

>>> print(F)
None

就像我们在键入F = None并贴上贴纸后所做的一样None


这就是所有的事情。实际上,Python附带了一些已经粘贴到对象上的标签(内置名称),但是其他一些标签则需要使用诸如F = "fork"and A = 2和这样的行来编写c17 = 3.14,然后再将其粘贴在其他对象上(例如F = 10or F = None;它们都是一样的) )

Briggs假装您可能要写的所有可能的贴纸均已粘贴到该None对象上。

Martijn’s answer explains what None is in Python, and correctly states that the book is misleading. Since Python programmers as a rule would never say

Assigning a value of None to a variable is one way to reset it to its original, empty state.

it’s hard to explain what Briggs means in a way which makes sense and explains why no one here seems happy with it. One analogy which may help:

In Python, variable names are like stickers put on objects. Every sticker has a unique name written on it, and it can only be on one object at a time, but you could put more than one sticker on the same object, if you wanted to. When you write

F = "fork"

you put the sticker “F” on a string object "fork". If you then write

F = None

you move the sticker to the None object.

What Briggs is asking you to imagine is that you didn’t write the sticker "F", there was already an F sticker on the None, and all you did was move it, from None to "fork". So when you type F = None, you’re “reset[ting] it to its original, empty state”, if we decided to treat None as meaning empty state.

I can see what he’s getting at, but that’s a bad way to look at it. If you start Python and type print(F), you see

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

and that NameError means Python doesn’t recognize the name F, because there is no such sticker. If Briggs were right and F = None resets F to its original state, then it should be there now, and we should see

>>> print(F)
None

like we do after we type F = None and put the sticker on None.


So that’s all that’s going on. In reality, Python comes with some stickers already attached to objects (built-in names), but others you have to write yourself with lines like F = "fork" and A = 2 and c17 = 3.14, and then you can stick them on other objects later (like F = 10 or F = None; it’s all the same.)

Briggs is pretending that all possible stickers you might want to write were already stuck to the None object.


回答 1

None只是通常用于表示“空”或“此处无值”的值。它是一个信号对象 ; 它仅具有含义,因为Python文档说明了它的含义。

在给定的Python解释器会话中,该对象只有一个副本。

例如,如果您编写一个函数,但该函数不使用显式return语句,None则返回该函数。这样,使用函数进行编程就大大简化了;一个函数总是返回某些东西,即使它只是那个None对象。

您可以明确地对其进行测试:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

另一个用途是为函数提供可选参数,默认为“空”:

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

该函数spam()有一个可选参数。如果在spam()未指定的情况下进行调用,则会为其指定默认值None,从而易于检测是否使用参数调用了该函数。

其他语言也有类似的概念。SQL有NULL; JavaScript具有undefined null,等等。

请注意,在Python中,变量通过使用而存在。您无需先声明变量,因此Python 中没有真正的变量。那么,将变量设置None为与将其设置为默认的空值是不同的。None也是一个值,尽管该值通常用于表示空白。您正在阅读的书在这一点上具有误导性。

None is just a value that commonly is used to signify ’empty’, or ‘no value here’. It is a signal object; it only has meaning because the Python documentation says it has that meaning.

There is only one copy of that object in a given Python interpreter session.

If you write a function, and that function doesn’t use an explicit return statement, None is returned instead, for example. That way, programming with functions is much simplified; a function always returns something, even if it is only that one None object.

You can test for it explicitly:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

Another use is to give optional parameters to functions an ’empty’ default:

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

The function spam() has a optional argument; if you call spam() without specifying it, the default value None is given to it, making it easy to detect if the function was called with an argument or not.

Other languages have similar concepts. SQL has NULL; JavaScript has undefined and null, etc.

Note that in Python, variables exist by virtue of being used. You don’t need to declare a variable first, so there are no really empty variables in Python. Setting a variable to None is then not the same thing as setting it to a default empty value; None is a value too, albeit one that is often used to signal emptyness. The book you are reading is misleading on that point.


回答 2

这就是Python文档必须说的None

types.NoneType的唯一值。当没有将默认参数传递给函数时,通常不使用None来表示缺少值。

在版本2.4中更改:分配为None是非法的,并引发SyntaxError。

注意不能重新分配名称None和debug(分配给它们,即使作为属性名称,也会引发SyntaxError),因此可以将它们视为“ true”常量。

  1. 让我们确认None第一个的类型

    print type(None)
    print None.__class__
    

    输出量

    <type 'NoneType'>
    <type 'NoneType'>
    

基本上,NoneType数据类型与intfloat等类似。您可以在8.15中查看Python中可用的默认类型列表types —内置类型的名称

  1. 并且,NoneNoneType类的实例。因此,我们可能要创建None自己的实例。让我们尝试一下

    print types.IntType()
    print types.NoneType()
    

    输出量

    0
    TypeError: cannot create 'NoneType' instances
    

很明显,无法创建NoneType实例。我们不必担心价值的独特性None

  1. 让我们检查一下我们是如何None内部实现的。

    print dir(None)

    输出量

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    

除了__setattr__,所有其他均为只读属性。因此,我们无法更改的属性None

  1. 让我们尝试为添加新属性 None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'
    

    输出量

    TypeError: can't set attributes of built-in/extension type 'NoneType'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    

上面看到的语句分别产生这些错误消息。这意味着,我们不能在None实例上动态创建属性。

  1. 让我们检查一下分配东西时会发生什么None。根据文档,它应该抛出SyntaxError。这意味着,如果我们向分配了某些内容None,则该程序将根本不会执行。

    None = 1

    输出量

    SyntaxError: cannot assign to None

我们已经确定

  1. None 是…的实例 NoneType
  2. None 不能有新属性
  3. 的现有属性None无法更改。
  4. 我们无法创建的其他实例 NoneType
  5. 我们甚至不能通过None给它分配值来更改对它的引用。

因此,如文档中所述,None实际上可以将其视为true constant

很高兴知道None:)

This is what the Python documentation has got to say about None:

The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function.

Changed in version 2.4: Assignments to None are illegal and raise a SyntaxError.

Note The names None and debug cannot be reassigned (assignments to them, even as an attribute name, raise SyntaxError), so they can be considered “true” constants.

  1. Let’s confirm the type of None first

    print type(None)
    print None.__class__
    

    Output

    <type 'NoneType'>
    <type 'NoneType'>
    

Basically, NoneType is a data type just like int, float, etc. You can check out the list of default types available in Python in 8.15. types — Names for built-in types.

  1. And, None is an instance of NoneType class. So we might want to create instances of None ourselves. Let’s try that

    print types.IntType()
    print types.NoneType()
    

    Output

    0
    TypeError: cannot create 'NoneType' instances
    

So clearly, cannot create NoneType instances. We don’t have to worry about the uniqueness of the value None.

  1. Let’s check how we have implemented None internally.

    print dir(None)
    

    Output

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    

Except __setattr__, all others are read-only attributes. So, there is no way we can alter the attributes of None.

  1. Let’s try and add new attributes to None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'
    

    Output

    TypeError: can't set attributes of built-in/extension type 'NoneType'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    

The above seen statements produce these error messages, respectively. It means that, we cannot create attributes dynamically on a None instance.

  1. Let us check what happens when we assign something None. As per the documentation, it should throw a SyntaxError. It means, if we assign something to None, the program will not be executed at all.

    None = 1
    

    Output

    SyntaxError: cannot assign to None
    

We have established that

  1. None is an instance of NoneType
  2. None cannot have new attributes
  3. Existing attributes of None cannot be changed.
  4. We cannot create other instances of NoneType
  5. We cannot even change the reference to None by assigning values to it.

So, as mentioned in the documentation, None can really be considered as a true constant.

Happy knowing None :)


回答 3

您所指的书显然是试图大大简化的含义None。Python的变量不具备初始,空状态- Python的变量绑定(只),他们定义的时候。如果不给它一个值,就不能创建一个Python变量。

>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'x' is not defined

但是有时候您想让一个函数根据变量是否定义而具有不同的含义。您可以创建默认值为的参数None

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

None在这种情况下,此值是特殊值并不十分重要。我可以使用任何默认值:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

…但是None到处都有给我们带来两个好处:

  1. 我们不必选择-1含义不明确的特殊值,并且
  2. 实际上,我们的函数可能需要-1作为普通输入处理。
>>> test(-1)
no x here

哎呀!

因此,这本书在使用“ 重设 ”一词时通常会产生一些误导–分配None名称是向程序员发出信号,表明该值未在使用中,或者该函数应以某种默认方式运行,但需要重设一个值要恢复其原始的未定义状态,您必须使用del关键字:

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

The book you refer to is clearly trying to greatly simplify the meaning of None. Python variables don’t have an initial, empty state – Python variables are bound (only) when they’re defined. You can’t create a Python variable without giving it a value.

>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'x' is not defined

but sometimes you want to make a function mean different things depending on whether a variable is defined or not. You can create an argument with a default value of None:

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

The fact that this value is the special None value is not terribly important in this case. I could’ve used any default value:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

…but having None around gives us two benefits:

  1. We don’t have to pick a special value like -1 whose meaning is unclear, and
  2. Our function may actually need to handle -1 as a normal input.
>>> test(-1)
no x here

oops!

So the book is a little misleading mostly in its use of the word reset – assigning None to a name is a signal to a programmer that that value isn’t being used or that the function should behave in some default way, but to reset a value to its original, undefined state you must use the del keyword:

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

回答 4

其他答案已经很好地解释了None的含义。但是,我仍然想通过一个例子对此进行更多说明。

例:

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

现在尝试猜测上面列表的输出。好吧,答案令人惊讶地如下:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

但为什么?

许多人会错误地期望list1等于[10]list3等于[‘a’],以为每次调用extendList时,list参数将被设置为其默认值[]

但是,实际发生的情况是,在定义函数时,仅会创建一次新的默认列表,然后在每次调用extendList且未指定list参数的情况下都使用同一列表。这是因为默认参数中的表达式是在定义函数时计算的,而不是在调用函数时计算的

因此,list1list3在同一默认列表上运行,而list2在它创建的单独列表上运行(通过传递其自己的空列表作为list参数的值)。


“无”救星:(修改上面的示例以产生所需的行为)

def extendList(val, list=None):
    if list is None:
       list = []
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

使用此修订的实现,输出将是:

list1 = [10]
list2 = [123]
list3 = ['a']

注意 -贷记至toptal.com的示例

Other answers have already explained meaning of None beautifully. However, I would still like to throw more light on this using an example.

Example:

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

Now try to guess output of above list. Well, the answer is surprisingly as below:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

But Why?

Many will mistakenly expect list1 to be equal to [10] and list3 to be equal to [‘a’], thinking that the list argument will be set to its default value of [] each time extendList is called.

However, what actually happens is that the new default list is created only once when the function is defined, and that same list is then used subsequently whenever extendList is invoked without a list argument being specified. This is because expressions in default arguments are calculated when the function is defined, not when it’s called.

list1 and list3 are therefore operating on the same default list, whereas list2 is operating on a separate list that it created (by passing its own empty list as the value for the list parameter).


‘None’ the savior: (Modify example above to produce desired behavior)

def extendList(val, list=None):
    if list is None:
       list = []
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

With this revised implementation, the output would be:

list1 = [10]
list2 = [123]
list3 = ['a']

Note – Example credit to toptal.com


回答 5

None是一个单例对象(意味着只有一个None),在语言和库中的许多地方都用于表示缺少其他值。


例如:
if d是一个字典,如果存在d.get(k)则返回d[k],但None如果d没有key 则返回k

从一个很棒的博客中阅读以下信息:http : //python-history.blogspot.in/

None is a singleton object (meaning there is only one None), used in many places in the language and library to represent the absence of some other value.


For example:
if d is a dictionary, d.get(k) will return d[k] if it exists, but None if d has no key k.

Read this info from a great blog: http://python-history.blogspot.in/


回答 6

所有这些都是很好的答案,但是我认为还有更多的原因可以解释None

想象一下,您在婚礼上收集了RSVP。您想记录每个人是否参加。如果他们正在参加,请设置person.attending = True。如果他们不参加,您设置person.attending = False。如果尚未收到任何RSVP,则person.attending = None。这样,您可以区分无信息None和否定答案。

All of these are good answers but I think there’s more to explain why None is useful.

Imagine you collecting RSVPs to a wedding. You want to record whether each person will attend. If they are attending, you set person.attending = True. If they are not attending you set person.attending = False. If you have not received any RSVP, then person.attending = None. That way you can distinguish between no information – None – and a negative answer.


回答 7

我喜欢代码示例(以及水果),所以让我告诉你

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

没有意味着什么,没有价值。

没有一个计算结果为False。

I love code examples (as well as fruit), so let me show you

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

None means nothing, it has no value.

None evaluates to False.


回答 8

largest=none
smallest =none 
While True :
          num =raw_input ('enter a number ') 
          if num =="done ": break 
          try :
           inp =int (inp) 
          except:
              Print'Invalid input' 
           if largest is none :
               largest=inp
           elif inp>largest:
                largest =none 
           print 'maximum', largest

          if smallest is none:
               smallest =none
          elif inp<smallest :
               smallest =inp
          print 'minimum', smallest 

print 'maximum, minimum, largest, smallest 
largest=none
smallest =none 
While True :
          num =raw_input ('enter a number ') 
          if num =="done ": break 
          try :
           inp =int (inp) 
          except:
              Print'Invalid input' 
           if largest is none :
               largest=inp
           elif inp>largest:
                largest =none 
           print 'maximum', largest

          if smallest is none:
               smallest =none
          elif inp<smallest :
               smallest =inp
          print 'minimum', smallest 

print 'maximum, minimum, largest, smallest 

如何计算列表中的唯一值

问题:如何计算列表中的唯一值

因此,我试图制作一个程序来询问用户输入并将值存储在数组/列表中。
然后,当输入空白行时,它将告诉用户这些值中有多少是唯一的。
我出于现实原因而不是问题集来构建它。

enter: happy
enter: rofl
enter: happy
enter: mpg8
enter: Cpp
enter: Cpp
enter:
There are 4 unique words!

我的代码如下:

# ask for input
ipta = raw_input("Word: ")

# create list 
uniquewords = [] 
counter = 0
uniquewords.append(ipta)

a = 0   # loop thingy
# while loop to ask for input and append in list
while ipta: 
  ipta = raw_input("Word: ")
  new_words.append(input1)
  counter = counter + 1

for p in uniquewords:

..这就是到目前为止我所获得的一切。
我不确定如何计算列表中单词的唯一数量?
如果有人可以发布解决方案,以便我可以学习它,或者至少告诉我它会是多么棒,谢谢!

So I’m trying to make this program that will ask the user for input and store the values in an array / list.
Then when a blank line is entered it will tell the user how many of those values are unique.
I’m building this for real life reasons and not as a problem set.

enter: happy
enter: rofl
enter: happy
enter: mpg8
enter: Cpp
enter: Cpp
enter:
There are 4 unique words!

My code is as follows:

# ask for input
ipta = raw_input("Word: ")

# create list 
uniquewords = [] 
counter = 0
uniquewords.append(ipta)

a = 0   # loop thingy
# while loop to ask for input and append in list
while ipta: 
  ipta = raw_input("Word: ")
  new_words.append(input1)
  counter = counter + 1

for p in uniquewords:

..and that’s about all I’ve gotten so far.
I’m not sure how to count the unique number of words in a list?
If someone can post the solution so I can learn from it, or at least show me how it would be great, thanks!


回答 0

另外,使用collections.Counter重构代码:

from collections import Counter

words = ['a', 'b', 'c', 'a']

Counter(words).keys() # equals to list(set(words))
Counter(words).values() # counts the elements' frequency

输出:

['a', 'c', 'b']
[2, 1, 1]

In addition, use collections.Counter to refactor your code:

from collections import Counter

words = ['a', 'b', 'c', 'a']

Counter(words).keys() # equals to list(set(words))
Counter(words).values() # counts the elements' frequency

Output:

['a', 'c', 'b']
[2, 1, 1]

回答 1

您可以使用集合删除重复项,然后使用len函数计算集合中的元素:

len(set(new_words))

You can use a set to remove duplicates, and then the len function to count the elements in the set:

len(set(new_words))

回答 2

values, counts = np.unique(words, return_counts=True)

values, counts = np.unique(words, return_counts=True)


回答 3

使用一

words = ['a', 'b', 'c', 'a']
unique_words = set(words)             # == set(['a', 'b', 'c'])
unique_word_count = len(unique_words) # == 3

有了这个,您的解决方案就可以很简单:

words = []
ipta = raw_input("Word: ")

while ipta:
  words.append(ipta)
  ipta = raw_input("Word: ")

unique_word_count = len(set(words))

print "There are %d unique words!" % unique_word_count

Use a set:

words = ['a', 'b', 'c', 'a']
unique_words = set(words)             # == set(['a', 'b', 'c'])
unique_word_count = len(unique_words) # == 3

Armed with this, your solution could be as simple as:

words = []
ipta = raw_input("Word: ")

while ipta:
  words.append(ipta)
  ipta = raw_input("Word: ")

unique_word_count = len(set(words))

print "There are %d unique words!" % unique_word_count

回答 4

aa="XXYYYSBAA"
bb=dict(zip(list(aa),[list(aa).count(i) for i in list(aa)]))
print(bb)
# output:
# {'X': 2, 'Y': 3, 'S': 1, 'B': 1, 'A': 2}
aa="XXYYYSBAA"
bb=dict(zip(list(aa),[list(aa).count(i) for i in list(aa)]))
print(bb)
# output:
# {'X': 2, 'Y': 3, 'S': 1, 'B': 1, 'A': 2}

回答 5

对于ndarray,有一个称为unique的numpy方法:

np.unique(array_name)

例子:

>>> np.unique([1, 1, 2, 2, 3, 3])
array([1, 2, 3])
>>> a = np.array([[1, 1], [2, 3]])
>>> np.unique(a)
array([1, 2, 3])

对于系列,有一个函数调用value_counts()

Series_name.value_counts()

For ndarray there is a numpy method called unique:

np.unique(array_name)

Examples:

>>> np.unique([1, 1, 2, 2, 3, 3])
array([1, 2, 3])
>>> a = np.array([[1, 1], [2, 3]])
>>> np.unique(a)
array([1, 2, 3])

For a Series there is a function call value_counts():

Series_name.value_counts()

回答 6

ipta = raw_input("Word: ") ## asks for input
words = [] ## creates list
unique_words = set(words)
ipta = raw_input("Word: ") ## asks for input
words = [] ## creates list
unique_words = set(words)

回答 7

尽管集合是最简单的方法,但是您也可以使用some_dict.has(key)字典并仅使用唯一的键和值来填充字典。

假设您已经填充words[]了用户的输入,请创建一个字典,将列表中的唯一单词映射到数字:

word_map = {}
i = 1
for j in range(len(words)):
    if not word_map.has_key(words[j]):
        word_map[words[j]] = i
        i += 1                                                             
num_unique_words = len(new_map) # or num_unique_words = i, however you prefer

Although a set is the easiest way, you could also use a dict and use some_dict.has(key) to populate a dictionary with only unique keys and values.

Assuming you have already populated words[] with input from the user, create a dict mapping the unique words in the list to a number:

word_map = {}
i = 1
for j in range(len(words)):
    if not word_map.has_key(words[j]):
        word_map[words[j]] = i
        i += 1                                                             
num_unique_words = len(new_map) # or num_unique_words = i, however you prefer

回答 8

使用熊猫的其他方法

import pandas as pd

LIST = ["a","a","c","a","a","v","d"]
counts,values = pd.Series(LIST).value_counts().values, pd.Series(LIST).value_counts().index
df_results = pd.DataFrame(list(zip(values,counts)),columns=["value","count"])

然后,您可以以任何所需的格式导出结果

Other method by using pandas

import pandas as pd

LIST = ["a","a","c","a","a","v","d"]
counts,values = pd.Series(LIST).value_counts().values, pd.Series(LIST).value_counts().index
df_results = pd.DataFrame(list(zip(values,counts)),columns=["value","count"])

You can then export results in any format you want


回答 9

怎么样:

import pandas as pd
#List with all words
words=[]

#Code for adding words
words.append('test')


#When Input equals blank:
pd.Series(words).nunique()

它返回列表中有多少个唯一值

How about:

import pandas as pd
#List with all words
words=[]

#Code for adding words
words.append('test')


#When Input equals blank:
pd.Series(words).nunique()

It returns how many unique values are in a list


回答 10

以下应该工作。lambda函数过滤掉重复的单词。

inputs=[]
input = raw_input("Word: ").strip()
while input:
    inputs.append(input)
    input = raw_input("Word: ").strip()
uniques=reduce(lambda x,y: ((y in x) and x) or x+[y], inputs, [])
print 'There are', len(uniques), 'unique words'

The following should work. The lambda function filter out the duplicated words.

inputs=[]
input = raw_input("Word: ").strip()
while input:
    inputs.append(input)
    input = raw_input("Word: ").strip()
uniques=reduce(lambda x,y: ((y in x) and x) or x+[y], inputs, [])
print 'There are', len(uniques), 'unique words'

回答 11

我会自己使用一套,但这是另一种方式:

uniquewords = []
while True:
    ipta = raw_input("Word: ")
    if ipta == "":
        break
    if not ipta in uniquewords:
        uniquewords.append(ipta)
print "There are", len(uniquewords), "unique words!"

I’d use a set myself, but here’s yet another way:

uniquewords = []
while True:
    ipta = raw_input("Word: ")
    if ipta == "":
        break
    if not ipta in uniquewords:
        uniquewords.append(ipta)
print "There are", len(uniquewords), "unique words!"

回答 12

ipta = raw_input("Word: ") ## asks for input
words = [] ## creates list

while ipta: ## while loop to ask for input and append in list
  words.append(ipta)
  ipta = raw_input("Word: ")
  words.append(ipta)
#Create a set, sets do not have repeats
unique_words = set(words)

print "There are " +  str(len(unique_words)) + " unique words!"
ipta = raw_input("Word: ") ## asks for input
words = [] ## creates list

while ipta: ## while loop to ask for input and append in list
  words.append(ipta)
  ipta = raw_input("Word: ")
  words.append(ipta)
#Create a set, sets do not have repeats
unique_words = set(words)

print "There are " +  str(len(unique_words)) + " unique words!"

在循环中如何创建不同的变量名?[重复]

问题:在循环中如何创建不同的变量名?[重复]

出于示例目的…

for x in range(0,9):
    string'x' = "Hello"

所以我最终得到了string1,string2,string3 …都等于“ Hello”

For example purposes…

for x in range(0,9):
    string'x' = "Hello"

So I end up with string1, string2, string3… all equaling “Hello”


回答 0

你当然可以; 它被称为字典

d = {}
for x in range(1, 10):
    d["string{0}".format(x)] = "Hello"
>>> d["string5"]
'Hello'
>>> d
{'string1': 'Hello',
 'string2': 'Hello',
 'string3': 'Hello',
 'string4': 'Hello',
 'string5': 'Hello',
 'string6': 'Hello',
 'string7': 'Hello',
 'string8': 'Hello',
 'string9': 'Hello'}

我说的有点难以理解,但实际上将一个值与另一个值相关联的最佳方法是字典。这就是它的设计目的!

Sure you can; it’s called a dictionary:

d = {}
for x in range(1, 10):
    d["string{0}".format(x)] = "Hello"
>>> d["string5"]
'Hello'
>>> d
{'string1': 'Hello',
 'string2': 'Hello',
 'string3': 'Hello',
 'string4': 'Hello',
 'string5': 'Hello',
 'string6': 'Hello',
 'string7': 'Hello',
 'string8': 'Hello',
 'string9': 'Hello'}

I said this somewhat tongue in check, but really the best way to associate one value with another value is a dictionary. That is what it was designed for!


回答 1

这真是个坏主意,但是…

for x in range(0, 9):
    globals()['string%s' % x] = 'Hello'

然后例如:

print(string3)

会给你:

Hello

但是,这是不好的做法。如其他人建议的那样,您应该改用字典或列表。当然,除非您真的想知道如何做,但不想使用它。

It is really bad idea, but…

for x in range(0, 9):
    globals()['string%s' % x] = 'Hello'

and then for example:

print(string3)

will give you:

Hello

However this is bad practice. You should use dictionaries or lists instead, as others propose. Unless, of course, you really wanted to know how to do it, but did not want to use it.


回答 2

一种方法是使用exec()。例如:

for k in range(5):
    exec(f'cat_{k} = k*2')
>>> print(cat_0)
0
>>> print(cat_1)
2
>>> print(cat_2)
4
>>> print(cat_3)
6
>>> print(cat_4)
8

在这里,我利用了Python 3.6+中方便的f字符串格式

One way you can do this is with exec(). For example:

for k in range(5):
    exec(f'cat_{k} = k*2')
>>> print(cat_0)
0
>>> print(cat_1)
2
>>> print(cat_2)
4
>>> print(cat_3)
6
>>> print(cat_4)
8

Here I am taking advantage of the handy f string formatting in Python 3.6+


回答 3

创建变量变量名根本没有意义。为什么?

  • 它们是不必要的:您可以将所有内容存储在列表,字典等中
  • 它们很难创建:您必须使用execglobals()
  • 您不能使用它们:如何编写使用这些变量的代码?您必须exec/globals()再次使用

使用列表要容易得多:

# 8 strings: `Hello String 0, .. ,Hello String 8`
strings = ["Hello String %d" % x for x in range(9)]
for string in strings: # you can loop over them
    print string
print string[6] # or pick any of them

It’s simply pointless to create variable variable names. Why?

  • They are unnecessary: You can store everything in lists, dictionarys and so on
  • They are hard to create: You have to use exec or globals()
  • You can’t use them: How do you write code that uses these variables? You have to use exec/globals() again

Using a list is much easier:

# 8 strings: `Hello String 0, .. ,Hello String 8`
strings = ["Hello String %d" % x for x in range(9)]
for string in strings: # you can loop over them
    print string
print string[6] # or pick any of them

回答 4

不要使用字典

import sys
this = sys.modules[__name__] # this is now your current namespace
for x in range(0,9):
    setattr(this, 'string%s' % x, 'Hello')

print string0
print string1
print string2
print string3
print string4
print string5
print string6
print string7
print string8

不要使用字典

globals()存在风险,因为它会给您提供当前命名空间指向的内容,但是这可能会发生变化,因此修改globals()的返回值不是一个好主意

Don’t do this use a dictionary

import sys
this = sys.modules[__name__] # this is now your current namespace
for x in range(0,9):
    setattr(this, 'string%s' % x, 'Hello')

print string0
print string1
print string2
print string3
print string4
print string5
print string6
print string7
print string8

don’t do this use a dict

globals() has risk as it gives you what the namespace is currently pointing to but this can change and so modifying the return from globals() is not a good idea


回答 5

for x in range(9):
    exec("string" + str(x) + " = 'hello'")

这应该工作。

for x in range(9):
    exec("string" + str(x) + " = 'hello'")

This should work.


回答 6

我会使用一个列表:

string = []
for i in range(0, 9):
  string.append("Hello")

这样,您将拥有9个“ Hello”,并且可以像这样单独获取它们:

string[x]

哪里 x可以找到您想要的“ Hello”。

因此,print(string[1])将打印Hello

I would use a list:

string = []
for i in range(0, 9):
  string.append("Hello")

This way, you would have 9 “Hello” and you could get them individually like this:

string[x]

Where x would identify which “Hello” you want.

So, print(string[1]) would print Hello.


回答 7

我认为这里的挑战不是要调用global()

我将为要保存的(动态)变量定义一个列表,然后将其附加到for循环中。然后使用单独的for循环查看每个条目,甚至执行其他操作。

这是一个示例-我在不同的分支机构都有许多网络交换机(例如2到8之间)。现在,我需要确保有一种方法可以确定在任何给定分支上有多少个可用交换机(或活动ping测试),然后对它们执行一些操作。

这是我的代码:

import requests
import sys

def switch_name(branchNum):
    # s is an empty list to start with
    s = []
    #this FOR loop is purely for creating and storing the dynamic variable names in s
    for x in range(1,8,+1):
        s.append("BR" + str(branchNum) + "SW0" + str(x))

    #this FOR loop is used to read each of the switch in list s and perform operations on
    for i in s:
        print(i,"\n")
        # other operations can be executed here too for each switch (i) - like SSH in using paramiko and changing switch interface VLAN etc.


def main():  

    # for example's sake - hard coding the site code
    branchNum= "123"
    switch_name(branchNum)


if __name__ == '__main__':
    main()

输出为:

BR123SW01

BR123SW02

BR123SW03

BR123SW04

BR123SW05

BR123SW06

BR123SW07

I think the challenge here is not to call upon global()

I would personally define a list for your (dynamic) variables to be held and then append to it within a for loop. Then use a separate for loop to view each entry or even execute other operations.

Here is an example – I have a number of network switches (say between 2 and 8) at various BRanches. Now I need to ensure I have a way to determining how many switches are available (or alive – ping test) at any given branch and then perform some operations on them.

Here is my code:

import requests
import sys

def switch_name(branchNum):
    # s is an empty list to start with
    s = []
    #this FOR loop is purely for creating and storing the dynamic variable names in s
    for x in range(1,8,+1):
        s.append("BR" + str(branchNum) + "SW0" + str(x))

    #this FOR loop is used to read each of the switch in list s and perform operations on
    for i in s:
        print(i,"\n")
        # other operations can be executed here too for each switch (i) - like SSH in using paramiko and changing switch interface VLAN etc.


def main():  

    # for example's sake - hard coding the site code
    branchNum= "123"
    switch_name(branchNum)


if __name__ == '__main__':
    main()

Output is:

BR123SW01

BR123SW02

BR123SW03

BR123SW04

BR123SW05

BR123SW06

BR123SW07


回答 8

使用字典应该是保留变量和关联值的正确方法,您可以使用以下方法:

dict_ = {}
for i in range(9):
     dict_['string%s' % i]  = 'Hello'

但是,如果要将变量添加到局部变量中,可以使用:

for i in range(9):
     exec('string%s = Hello' % i)

例如,如果要为它们分配值0到8,则可以使用:

for i in range(9):
     exec('string%s = %s' % (i,i))

Using dictionaries should be right way to keep the variables and associated values, and you may use this:

dict_ = {}
for i in range(9):
     dict_['string%s' % i]  = 'Hello'

But if you want to add the variables to the local variables you can use:

for i in range(9):
     exec('string%s = Hello' % i)

And for example if you want to assign values 0 to 8 to them, you may use:

for i in range(9):
     exec('string%s = %s' % (i,i))

回答 9

字典可以包含值,并且可以使用update()方法添加值。您希望系统创建变量,因此您应该知道保留位置。

variables = {}
break_condition= True # Dont forget to add break condition to while loop if you dont want your system to go crazy.
name = variable
i = 0 
name = name + str(i) #this will be your variable name.
while True:
    value = 10 #value to assign
    variables.update(
                  {name:value})
    if break_condition == True:
        break

Dictionary can contain values and values can be added by using update() method. You want your system to create variables, so you should know where to keep.

variables = {}
break_condition= True # Dont forget to add break condition to while loop if you dont want your system to go crazy.
name = “variable”
i = 0 
name = name + str(i) #this will be your variable name.
while True:
    value = 10 #value to assign
    variables.update(
                  {name:value})
    if break_condition == True:
        break

Python中的实例变量与类变量

问题:Python中的实例变量与类变量

我有Python类,在运行时我只需要一个实例,因此每个类仅一个属性,而每个实例仅具有一个属性就足够了。如果将有多个实例(不会发生),则所有实例都应具有相同的配置。我不知道以下哪个选项会更好或更“惯用” Python。

类变量:

class MyController(Controller):

  path = "something/"
  children = [AController, BController]

  def action(self, request):
    pass

实例变量:

class MyController(Controller):

  def __init__(self):
    self.path = "something/"
    self.children = [AController, BController]

  def action(self, request):
    pass

I have Python classes, of which I need only one instance at runtime, so it would be sufficient to have the attributes only once per class and not per instance. If there would be more than one instance (which won’t happen), all instance should have the same configuration. I wonder which of the following options would be better or more “idiomatic” Python.

Class variables:

class MyController(Controller):

  path = "something/"
  children = [AController, BController]

  def action(self, request):
    pass

Instance variables:

class MyController(Controller):

  def __init__(self):
    self.path = "something/"
    self.children = [AController, BController]

  def action(self, request):
    pass

回答 0

如果您仍然只有一个实例,那么最好每个实例都设置所有变量,这仅仅是因为它们的访问速度(稍微快一点)(由于类与实例之间的“继承性”,因此“查找”的级别降低了),而且没有不利的一面来抵消这一小优势。

If you have only one instance anyway, it’s best to make all variables per-instance, simply because they will be accessed (a little bit) faster (one less level of “lookup” due to the “inheritance” from class to instance), and there are no downsides to weigh against this small advantage.


回答 1

进一步呼应MikeAlex的建议,并添加我自己的颜色…

使用实例属性是典型的……更加惯用的Python。由于类属性的用例是特定的,因此未使用过多的类属性。静态方法和类方法与“普通”方法一样。它们是解决特定用例的特殊结构,否则它是由异常的程序员创建的代码,目的是炫耀他们知道Python编程的一些晦涩之处。

Alex在他的答复中提到,由于查找级别降低了,访问将(稍微快一些)……让我进一步澄清那些还不知道如何工作的人。它与变量访问非常相似-搜索顺序为:

  1. 当地人
  2. 非本地人
  3. 全球
  4. 内建

对于属性访问,顺序为:

  1. 实例
  2. MRO确定的基本类(方法解析顺序)

两种技术都以“由内而外”的方式工作,这意味着首先检查大多数局部对象,然后依次检查外层。

在上面的示例中,假设您正在查找path属性。当遇到“ self.path”之类的引用时,Python将首先查看实例属性以进行匹配。如果失败,它将检查实例化对象的类。最后,它将搜索基类。如Alex所述,如果在实例中找到您的属性,则无需在其他地方查找,因此节省了一点时间。

但是,如果您坚持使用类属性,则需要进行额外的查找。或者,您的另一种选择是通过类而不是实例来引用对象,例如,MyController.path代替self.path。这是一个直接查找,可以绕开延迟查找,但是正如alex在下面提到的那样,它是一个全局变量,因此您丢失了原本想保存的那一部分(除非您创建对[global]类名的本地引用) )。

最重要的是,您应该在大多数时间使用实例属性。但是,在某些情况下,类属性是适合该工作的工具。同时使用这两个代码将需要最大的努力,因为使用self只会使您获得实例属性对象,并且可以通过影子访问相同名称的class属性。在这种情况下,必须使用通过类名访问属性,以便对其进行引用。

Further echoing Mike’s and Alex’s advice and adding my own color…

Using instance attributes are the typical… the more idiomatic Python. Class attributes are not used used as much, since their use cases are specific. The same is true for static and class methods vs. “normal” methods. They’re special constructs addressing specific use cases, else it’s code created by an aberrant programmer wanting to show off they know some obscure corner of Python programming.

Alex mentions in his reply that access will be (a little bit) faster due to one less level of lookup… let me further clarify for those who don’t know about how this works yet. It is very similar to variable access — the search order of which is:

  1. locals
  2. nonlocals
  3. globals
  4. built-ins

For attribute access, the order is:

  1. instance
  2. class
  3. base classes as determined by the MRO (method resolution order)

Both techniques work in an “inside-out” manner, meaning the most local objects are checked first, then outer layers are checked in succession.

In your example above, let’s say you’re looking up the path attribute. When it encounters a reference like “self.path“, Python will look at the instance attributes first for a match. When that fails, it checks the class from which the object was instantiated from. Finally, it will search the base classes. As Alex stated, if your attribute is found in the instance, it doesn’t need to look elsewhere, hence your little bit of time savings.

However, if you insist on class attributes, you need that extra lookup. Or, your other alternative is to refer to the object via the class instead of the instance, e.g., MyController.path instead of self.path. That’s a direct lookup which will get around the deferred lookup, but as alex mentions below, it’s a global variable, so you lose that bit that you thought you were going to save (unless you create a local reference to the [global] class name).

The bottom-line is that you should use instance attributes most of the time. However, there will be occasions where a class attribute is the right tool for the job. Code using both at the same time will require the most diligence, because using self will only get you the instance attribute object and shadows access to the class attribute of the same name. In this case, you must use access the attribute by the class name in order to reference it.


回答 2

如有疑问,您可能需要实例属性。

类属性最好保留给有意义的特殊情况。唯一非常常见的用例是方法。对实例需要知道的只读常量使用类属性并不罕见(尽管这样做的唯一好处是,如果您还希望从类外部进行访问),但是对于在其中存储任何状态,您一定要谨慎,这很少是您想要的。即使您只有一个实例,也应该像编写其他实例一样编写类,这通常意味着使用实例属性。

When in doubt, you probably want an instance attribute.

Class attributes are best reserved for special cases where they make sense. The only very-common use case is methods. It isn’t uncommon to use class attributes for read-only constants that instances need to know (though the only benefit to this is if you also want access from outside the class), but you should certainly be cautious about storing any state in them, which is seldom what you want. Even if you will only have one instance, you should write the class like you would any other, which usually means using instance attributes.


回答 3

关于在Python中访问类变量的性能存在相同的问题-此处的代码改编自@Edward Loper

局部变量是访问最快的,与模块变量,类变量,实例变量密切相关。

您可以从以下四个范围访问变量:

  1. 实例变量(self.varname)
  2. 类变量(Classname.varname)
  3. 模块变量(VARNAME)
  4. 局部变量(变量名)

考试:

import timeit

setup='''
XGLOBAL= 5
class A:
    xclass = 5
    def __init__(self):
        self.xinstance = 5
    def f1(self):
        xlocal = 5
        x = self.xinstance
    def f2(self):
        xlocal = 5
        x = A.xclass
    def f3(self):
        xlocal = 5
        x = XGLOBAL
    def f4(self):
        xlocal = 5
        x = xlocal
a = A()
'''
print('access via instance variable: %.3f' % timeit.timeit('a.f1()', setup=setup, number=300000000) )
print('access via class variable: %.3f' % timeit.timeit('a.f2()', setup=setup, number=300000000) )
print('access via module variable: %.3f' % timeit.timeit('a.f3()', setup=setup, number=300000000) )
print('access via local variable: %.3f' % timeit.timeit('a.f4()', setup=setup, number=300000000) )

结果:

access via instance variable: 93.456
access via class variable: 82.169
access via module variable: 72.634
access via local variable: 72.199

Same question at Performance of accessing class variables in Python – the code here adapted from @Edward Loper

Local Variables are the fastest to access, pretty much tied with Module Variables, followed by Class Variables, followed by Instance Variables.

There are 4 scopes you can access variables from:

  1. Instance Variables (self.varname)
  2. Class Variables (Classname.varname)
  3. Module Variables (VARNAME)
  4. Local Variables (varname)

The test:

import timeit

setup='''
XGLOBAL= 5
class A:
    xclass = 5
    def __init__(self):
        self.xinstance = 5
    def f1(self):
        xlocal = 5
        x = self.xinstance
    def f2(self):
        xlocal = 5
        x = A.xclass
    def f3(self):
        xlocal = 5
        x = XGLOBAL
    def f4(self):
        xlocal = 5
        x = xlocal
a = A()
'''
print('access via instance variable: %.3f' % timeit.timeit('a.f1()', setup=setup, number=300000000) )
print('access via class variable: %.3f' % timeit.timeit('a.f2()', setup=setup, number=300000000) )
print('access via module variable: %.3f' % timeit.timeit('a.f3()', setup=setup, number=300000000) )
print('access via local variable: %.3f' % timeit.timeit('a.f4()', setup=setup, number=300000000) )

The result:

access via instance variable: 93.456
access via class variable: 82.169
access via module variable: 72.634
access via local variable: 72.199

如何在python中保存和恢复多个变量?

问题:如何在python中保存和恢复多个变量?

我需要将大约十二个对象保存到文件中,然后稍后将其还原。我尝试过使用带咸菜和搁置的for循环,但效果不佳。

编辑。
我试图保存的所有对象都在同一个类中(我之前应该提到过),但我没有意识到我可以像这样保存整个类:

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

I need to save about a dozen objects to a file and then restore them later. I’ve tried to use a for loop with pickle and shelve but it didn’t work right.

Edit.
All of the objects that I was trying to save were in the same class (I should have mentioned this before), and I didn’t realize that I could just save the whole class like this:

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

回答 0

如果需要保存多个对象,则可以简单地将它们放在单个列表或元组中,例如:

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

如果您有大量数据,可以通过传递protocol=-1dump(); 来减小文件大小。pickle然后将使用最佳的可用协议,而不是默认的历史记录(以及向后兼容的协议)。在这种情况下,必须以二进制模式打开文件(分别为wbrb)。

二进制模式也应该与Python 3一起使用,因为它的默认协议会生成二进制(即非文本)数据(写入模式'wb'和读取模式'rb')。

If you need to save multiple objects, you can simply put them in a single list, or tuple, for instance:

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

If you have a lot of data, you can reduce the file size by passing protocol=-1 to dump(); pickle will then use the best available protocol instead of the default historical (and more backward-compatible) protocol. In this case, the file must be opened in binary mode (wb and rb, respectively).

The binary mode should also be used with Python 3, as its default protocol produces binary (i.e. non-text) data (writing mode 'wb' and reading mode 'rb').


回答 1

有一个名为的内置库pickle。使用,pickle您可以将对象转储到文件中并在以后加载它们。

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

There is a built-in library called pickle. Using pickle you can dump objects to a file and load them later.

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

回答 2

您应该查看一下货架泡菜模块。如果您需要存储大量数据,最好使用数据库

You should look at the shelve and pickle modules. If you need to store a lot of data it may be better to use a database


回答 3

将多个变量保存到pickle文件的另一种方法是:

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

Another approach to saving multiple variables to a pickle file is:

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

回答 4

您可以使用klepto,它为内存,磁盘或数据库提供持久缓存。

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> db.dump()
>>> 

然后,在解释器重新启动后…

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

在此处获取代码:https : //github.com/uqfoundation

You could use klepto, which provides persistent caching to memory, disk, or database.

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> db.dump()
>>> 

Then, after interpreter restart…

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

Get the code here: https://github.com/uqfoundation


回答 5

以下方法似乎很简单,可以与不同大小的变量一起使用:

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

The following approach seems simple and can be used with variables of different size:

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

同时声明多个变量的更优雅的方式

问题:同时声明多个变量的更优雅的方式

要在“相同时间”声明多个变量,我会这样做:

a, b = True, False

但是,如果我不得不声明更多的变量,它将变得越来越不优雅:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True

有没有更好/优雅/方便的方法来做到这一点?

这必须是非常基本的,但是如果我确实使用列表或元组来存储变量,那么我将不得不如何处理,因为这样会有所帮助:

aList = [a,b]

无效,我必须这样做:

a, b = True, True

还是我想念什么?

To declare multiple variables at the “same time” I would do:

a, b = True, False

But if I had to declare much more variables, it turns less and less elegant:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True

Is there a better / elegant / convenient way to do this?

This must be very basic, but if I do used a list or a tuple for storing the variables, how would I have to approach so that I would be helpful since:

aList = [a,b]

Is not valid, I would have to do:

a, b = True, True

Or what am I missing?


回答 0

正如其他人所建议的那样,不太可能将10个不同的局部变量与布尔值一起使用是编写例程的最佳方法(尤其是如果它们确实具有一个字母的名称时:)

根据您正在执行的操作,可以改用词典。例如,如果要为一组单字母标志设置布尔值预设值,则可以执行以下操作:

>>> flags = dict.fromkeys(["a", "b", "c"], True)
>>> flags.update(dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

如果您愿意,也可以使用一个赋值语句来做到这一点:

>>> flags = dict(dict.fromkeys(["a", "b", "c"], True),
...              **dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

第二个参数dict并非完全为此目的而设计的:它的真正含义是允许您使用关键字参数(如)来覆盖字典中的各个元素d=False。上面的代码将表达式的结果**分解为一组关键字参数,这些参数传递给调用的函数。这无疑是创建字典的可靠方法,人们似乎至少接受了这种习语,但我怀疑有人可能认为它是非Python的。 </disclaimer>


另一种方法,这是最直观的,如果你会经常使用这种模式,是定义你的数据作为标志值(列表TrueFalse映射到标志名(单字符串))。然后,您可以将此数据定义转换为反向字典,该字典将标志名称映射到标志值。使用嵌套列表理解可以很简洁地完成此操作,但是这是一个非常易读的实现:

>>> def invert_dict(inverted_dict):
...     elements = inverted_dict.iteritems()
...     for flag_value, flag_names in elements:
...         for flag_name in flag_names:
...             yield flag_name, flag_value
... 
>>> flags = {True: ["a", "b", "c"], False: ["d", "e"]}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

该函数invert_dict是一个生成器函数。它生成产生 -意味着它反复返回 -键值对的值。这些键值对与初始flags字典的两个元素的内容相反。它们被送入dict构造函数。在这种情况下,dict构造函数的工作方式与上面的有所不同,因为构造函数被作为迭代器而非字典作为参数。


借鉴@Chris Lutz的评论:如果您真的将其用于单字符值,则实际上可以

>>> flags = {True: 'abc', False: 'de'}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

这是可行的,因为Python字符串是可迭代的,这意味着它们可以逐值移动。对于字符串,值是字符串中的各个字符。因此,当它们被解释为可迭代时,例如在这种情况下,它们在for循环中使用,['a', 'b', 'c']并且'abc'等效。另一个示例是将它们传递给需要迭代的函数时,例如tuple

我个人不会这样做,因为它不能直观地理解:当我看到一个字符串时,我希望它可以用作单个值而不是列表。因此,我看第一行并认为:“好的,所以有一个True标志和一个False标志。” 因此,尽管有可能,但我不认为这是可行的方法。从好的方面来说,这可能有助于更清楚地解释可迭代和迭代器的概念。


定义函数invert_dict以使其实际上返回字典也不是坏主意。我大多只是不这样做,因为它并不能真正帮助解释例程的工作原理。


显然,Python 2.7具有字典理解功能,这将为实现该功能提供一种极为简洁的方法。这留给读者练习,因为我没有安装Python 2.7 :)

您还可以结合功能广泛的itertools模块中的某些功能。正如他们所说的,有不止一种方法可以做到。等等,Python人士不这么说。好吧,在某些情况下还是如此。我猜想Guido已经给了我们字典理解能力,所以会有一种明显的方式来做到这一点。

As others have suggested, it’s unlikely that using 10 different local variables with Boolean values is the best way to write your routine (especially if they really have one-letter names :)

Depending on what you’re doing, it may make sense to use a dictionary instead. For example, if you want to set up Boolean preset values for a set of one-letter flags, you could do this:

>>> flags = dict.fromkeys(["a", "b", "c"], True)
>>> flags.update(dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

If you prefer, you can also do it with a single assignment statement:

>>> flags = dict(dict.fromkeys(["a", "b", "c"], True),
...              **dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

The second parameter to dict isn’t entirely designed for this: it’s really meant to allow you to override individual elements of the dictionary using keyword arguments like d=False. The code above blows up the result of the expression following ** into a set of keyword arguments which are passed to the called function. This is certainly a reliable way to create dictionaries, and people seem to be at least accepting of this idiom, but I suspect that some may consider it Unpythonic. </disclaimer>


Yet another approach, which is likely the most intuitive if you will be using this pattern frequently, is to define your data as a list of flag values (True, False) mapped to flag names (single-character strings). You then transform this data definition into an inverted dictionary which maps flag names to flag values. This can be done quite succinctly with a nested list comprehension, but here’s a very readable implementation:

>>> def invert_dict(inverted_dict):
...     elements = inverted_dict.iteritems()
...     for flag_value, flag_names in elements:
...         for flag_name in flag_names:
...             yield flag_name, flag_value
... 
>>> flags = {True: ["a", "b", "c"], False: ["d", "e"]}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

The function invert_dict is a generator function. It generates, or yields — meaning that it repeatedly returns values of — key-value pairs. Those key-value pairs are the inverse of the contents of the two elements of the initial flags dictionary. They are fed into the dict constructor. In this case the dict constructor works differently from above because it’s being fed an iterator rather than a dictionary as its argument.


Drawing on @Chris Lutz’s comment: If you will really be using this for single-character values, you can actually do

>>> flags = {True: 'abc', False: 'de'}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

This works because Python strings are iterable, meaning that they can be moved through value by value. In the case of a string, the values are the individual characters in the string. So when they are being interpreted as iterables, as in this case where they are being used in a for loop, ['a', 'b', 'c'] and 'abc' are effectively equivalent. Another example would be when they are being passed to a function that takes an iterable, like tuple.

I personally wouldn’t do this because it doesn’t read intuitively: when I see a string, I expect it to be used as a single value rather than as a list. So I look at the first line and think “Okay, so there’s a True flag and a False flag.” So although it’s a possibility, I don’t think it’s the way to go. On the upside, it may help to explain the concepts of iterables and iterators more clearly.


Defining the function invert_dict such that it actually returns a dictionary is not a bad idea either; I mostly just didn’t do that because it doesn’t really help to explain how the routine works.


Apparently Python 2.7 has dictionary comprehensions, which would make for an extremely concise way to implement that function. This is left as an exercise to the reader, since I don’t have Python 2.7 installed :)

You can also combine some functions from the ever-versatile itertools module. As they say, There’s More Than One Way To Do It. Wait, the Python people don’t say that. Well, it’s true anyway in some cases. I would guess that Guido hath given unto us dictionary comprehensions so that there would be One Obvious Way to do this.


回答 1

a, b, c, d, e, g, h, i, j = (True,)*9
f = False
a, b, c, d, e, g, h, i, j = (True,)*9
f = False

回答 2

使用列表/字典或定义自己的类来封装您要定义的内容,但是如果需要所有这些变量,则可以执行以下操作:

a = b = c = d = e = g = h = i = j = True
f = False

Use a list/dictionary or define your own class to encapsulate the stuff you’re defining, but if you need all those variables you can do:

a = b = c = d = e = g = h = i = j = True
f = False

回答 3

这是@Jeff M和我的评论的详细说明。

执行此操作时:

a, b = c, d

它适用于元组打包和拆包。您可以分开包装和拆箱步骤:

_ = c, d
a, b = _

第一行创建一个称为的元组_,其中包含两个元素,第一个元素的值为,c第二个元素的值为d。第二行将_元组解压缩到变量a和中b。这打破了您的一句话:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True, True, True, True

分成两行:

_ = True, True, True, True, True, False, True, True, True, True
a, b, c, d, e, f, g, h, i, j = _

它会为您提供与第一行完全相同的结果(如果将值或变量添加到一个部分而忘记更新另一个部分,则包括相同的exceptions)。但是,在这种特定情况下,yan的答案也许是最好的。

如果您有值列表,则仍然可以解压它们。您只需要先将其转换为元组即可。例如,以下代码将分别为a到分配一个介于0和9之间的值j

a, b, c, d, e, f, g, h, i, j = tuple(range(10))

编辑:巧妙地把所有元素都分配为true,元素5(变量f)除外:

a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10))

This is an elaboration on @Jeff M‘s and my comments.

When you do this:

a, b = c, d

It works with tuple packing and unpacking. You can separate the packing and unpacking steps:

_ = c, d
a, b = _

The first line creates a tuple called _ which has two elements, the first with the value of c and the second with the value of d. The second line unpacks the _ tuple into the variables a and b. This breaks down your one huge line:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True, True, True, True

Into two smaller lines:

_ = True, True, True, True, True, False, True, True, True, True
a, b, c, d, e, f, g, h, i, j = _

It will give you the exact same result as the first line (including the same exception if you add values or variables to one part but forget to update the other). However, in this specific case, yan’s answer is perhaps the best.

If you have a list of values, you can still unpack them. You just have to convert it to a tuple first. For example, the following will assign a value between 0 and 9 to each of a through j, respectively:

a, b, c, d, e, f, g, h, i, j = tuple(range(10))

EDIT: Neat trick to assign all of them as true except element 5 (variable f):

a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10))

回答 4

当人们建议“使用列表,元组或其他数据结构”时,他们的意思是,当您关心许多不同的值时,将它们分别命名为局部变量可能不是最好的方法做事情。

取而代之的是,您可能希望将它们收集到一个更大的数据结构中,该结构可以存储在单个局部变量中。

直观的演示了如何使用字典来实现此目的,克里斯·卢茨(Chris Lutz)演示了在拆分成单独的变量之前如何使用元组进行临时存储,但是要考虑的另一种选择是使用collections.namedtuple更永久地捆绑值。

因此,您可以执行以下操作:

# Define the attributes of our named tuple
from collections import namedtuple
DataHolder = namedtuple("DataHolder", "a b c d e f g")

# Store our data
data = DataHolder(True, True, True, True, True, False, True)

# Retrieve our data
print(data)
print(data.a, data.f)

当然,实际代码希望使用比“ DataHolder”和字母更大的有意义的名称。

When people are suggesting “use a list or tuple or other data structure”, what they’re saying is that, when you have a lot of different values that you care about, naming them all separately as local variables may not be the best way to do things.

Instead, you may want to gather them together into a larger data structure that can be stored in a single local variable.

intuited showed how you might use a dictionary for this, and Chris Lutz showed how to use a tuple for temporary storage before unpacking into separate variables, but another option to consider is to use collections.namedtuple to bundle the values more permanently.

So you might do something like:

# Define the attributes of our named tuple
from collections import namedtuple
DataHolder = namedtuple("DataHolder", "a b c d e f g")

# Store our data
data = DataHolder(True, True, True, True, True, False, True)

# Retrieve our data
print(data)
print(data.a, data.f)

Real code would hopefully use more meaningful names than “DataHolder” and the letters of the alphabet, of course.


回答 5

实际上是什么问题?

如果您确实需要或想要10 abcdefghij,则一次或一次别无其他可能写a并写b并写c。 ….

如果所有值都不相同,则您将不得不写出示例

a = 12
b= 'sun'
c = A() #(where A is a class)
d = range(1,102,5)
e = (line in filehandler if line.rstrip())
f = 0,12358
g = True
h = random.choice
i = re.compile('^(!=  ab).+?<span>')
j = [78,89,90,0]

也就是说,分别定义“变量”。

或者,使用另一种文字,无需使用_

a,b,c,d,e,f,g,h,i,j =\
12,'sun',A(),range(1,102,5),\
(line for line in filehandler if line.rstrip()),\
0.12358,True,random.choice,\
re.compile('^(!=  ab).+?<span>'),[78,89,90,0]

要么

a,b,c,d,e,f,g,h,i,j =\
(12,'sun',A(),range(1,102,5),
 (line for line in filehandler if line.rstrip()),
 0.12358,True,random.choice,
 re.compile('^(!=  ab).+?<span>'),[78,89,90,0])

如果其中一些必须具有相同的值,那就是写的时间太长的问题

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True 

然后您可以编写:

a=b=c=d=e=g=h=i=k=j=True
f = False

我不明白您到底是什么问题。如果要编写代码,则必须使用编写说明和定义所需的字符。还有什么 ?

我想知道您的问题是否不是您误解了某些东西的迹象。

当一个人写的时候a = 10不要以“其值可以改变的内存块”的意义创建一个变量。该指令:

  • 要么触发类型integer和值10 的对象的创建,要么触发名称“ a”与此对象在当前命名空间中的绑定

  • 或将命名空间中的名称“ a”重新分配给对象10(因为先前已将“ a”绑定到了另一个对象)

我说这是因为我看不到该实用程序定义10个标识符a,b,c …指向False或True。如果在执行过程中这些值未更改,为什么要使用10个标识符?如果更改了,为什么要先定义标识符?如果没有事先定义,则会在需要时创建它们

你的问题对我来说很奇怪

What’s the problem , in fact ?

If you really need or want 10 a, b, c, d, e, f, g, h, i, j , there will be no other possibility, at a time or another, to write a and write b and write c…..

If the values are all different, you will be obliged to write for exemple

a = 12
b= 'sun'
c = A() #(where A is a class)
d = range(1,102,5)
e = (line in filehandler if line.rstrip())
f = 0,12358
g = True
h = random.choice
i = re.compile('^(!=  ab).+?<span>')
j = [78,89,90,0]

that is to say defining the “variables” individually.

Or , using another writing, no need to use _ :

a,b,c,d,e,f,g,h,i,j =\
12,'sun',A(),range(1,102,5),\
(line for line in filehandler if line.rstrip()),\
0.12358,True,random.choice,\
re.compile('^(!=  ab).+?<span>'),[78,89,90,0]

or

a,b,c,d,e,f,g,h,i,j =\
(12,'sun',A(),range(1,102,5),
 (line for line in filehandler if line.rstrip()),
 0.12358,True,random.choice,
 re.compile('^(!=  ab).+?<span>'),[78,89,90,0])

.

If some of them must have the same value, is the problem that it’s too long to write

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True 

?

Then you can write:

a=b=c=d=e=g=h=i=k=j=True
f = False

.

I don’t understand what is exactly your problem. If you want to write a code, you’re obliged to use the characters required by the writing of the instructions and definitions. What else ?

I wonder if your question isn’t the sign that you misunderstand something.

When one writes a = 10 , one don’t create a variable in the sense of “chunk of memory whose value can change”. This instruction:

  • either triggers the creation of an object of type integer and value 10 and the binding of a name ‘a’ with this object in the current namespace

  • or re-assign the name ‘a’ in the namespace to the object 10 (because ‘a’ was precedently binded to another object)

I say that because I don’t see the utility to define 10 identifiers a,b,c… pointing to False or True. If these values don’t change during the execution, why 10 identifiers ? And if they change, why defining the identifiers first ?, they will be created when needed if not priorly defined

Your question appears weird to me


回答 6

听起来您正以错误的方式对待我。

重写您的代码以使用元组或编写一个类来存储所有数据。

Sounds like you’re approaching your problem the wrong way to me.

Rewrite your code to use a tuple or write a class to store all of the data.


回答 7

我喜欢投票最多的答案;但是,它存在清单所示的问题。

  >> a, b = ([0]*5,)*2
  >> print b
  [0, 0, 0, 0, 0]
  >> a[0] = 1
  >> print b
  [1, 0, 0, 0, 0]

对此进行了详细的讨论(在此),但要点是ab都是相同的,并且带有a is breturn True(与相同id(a) == id(b))。因此,如果您更改索引,你正在改变两者的指数ab,因为它们是联系在一起的。为了解决这个问题,你可以做(源)

>> a, b = ([0]*5 for i in range(2))
>> print b
[0, 0, 0, 0, 0]
>> a[0] = 1
>> print b
[0, 0, 0, 0, 0]

然后可以将其用作最佳答案的变体,其具有“所需的”直观结果

>> a, b, c, d, e, g, h, i = (True for i in range(9))
>> f = (False for i in range(1)) #to be pedantic

I like the top voted answer; however, it has problems with list as shown.

  >> a, b = ([0]*5,)*2
  >> print b
  [0, 0, 0, 0, 0]
  >> a[0] = 1
  >> print b
  [1, 0, 0, 0, 0]

This is discussed in great details (here), but the gist is that a and b are the same object with a is b returning True (same for id(a) == id(b)). Therefore if you change an index, you are changing the index of both a and b, since they are linked. To solve this you can do (source)

>> a, b = ([0]*5 for i in range(2))
>> print b
[0, 0, 0, 0, 0]
>> a[0] = 1
>> print b
[0, 0, 0, 0, 0]

This can then be used as a variant of the top answer, which has the “desired” intuitive results

>> a, b, c, d, e, g, h, i = (True for i in range(9))
>> f = (False for i in range(1)) #to be pedantic

回答 8

在您的情况下,我将使用YAML。

这是处理多个参数的一种优雅而专业的标准。这些值是从单独的文件加载的。您可以在此链接中看到一些信息:

https://keleshev.com/yaml-quick-introduction

但是,对于Google来说,它比较容易,因为它是一种标准,因此有成百上千的信息,您可以找到最适合您的理解的信息。;)

最好的祝福。

In your case, I would use YAML .

That is an elegant and professional standard for dealing with multiple parameters. The values are loaded from a separate file. You can see some info in this link:

https://keleshev.com/yaml-quick-introduction

But it is easier to Google it, as it is a standard, there are hundreds of info about it, you can find what best fits to your understanding. ;)

Best regards.


回答 9

JavaScript一样,您也可以在python的一行上使用多个语句a = 1; b = "Hello World"; c += 3

Like JavaScript you can also use multiple statements on one line in python a = 1; b = "Hello World"; c += 3


创建单独变量字典的更简单方法?

问题:创建单独变量字典的更简单方法?

我希望能够以字符串的形式获取变量的名称,但是我不知道Python是否具有这么多的自省功能。就像是:

>>> print(my_var.__name__)
'my_var'

我想这样做是因为我想将一堆变量变成一个像这样的字典:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

但是我想要比这更自动的东西。

Python具有locals()vars(),所以我猜有办法。

I would like to be able to get the name of a variable as a string but I don’t know if Python has that much introspection capabilities. Something like:

>>> print(my_var.__name__)
'my_var'

I want to do that because I have a bunch of variables I’d like to turn into a dictionary like :

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

But I’d like something more automatic than that.

Python have locals() and vars(), so I guess there is a way.


回答 0

您是否正在尝试这样做?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

Are you trying to do this?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

Example

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

回答 1

正如unwind所说,这实际上不是您在Python中所做的事情-变量实际上是到对象的名称映射。

但是,这是尝试的一种方法:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

As unwind said, this isn’t really something you do in Python – variables are actually name mappings to objects.

However, here’s one way to try and do it:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

回答 2

我已经很想这样做了。这种破解与rlotun的建议非常相似,但它是单行的,这对我很重要:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

Python 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

I’ve wanted to do this quite a lot. This hack is very similar to rlotun’s suggestion, but it’s a one-liner, which is important to me:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

Python 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

回答 3

这是一个hack。不适用于所有Python实现发行版(尤其是那些没有的发行版traceback.extract_stack)。

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

请注意,此hack很脆弱:

make_dict(bar,
          foo)

(在2行上调用make_dict)将不起作用。

与其尝试根据 foo and bar来生成dict,不如使用字符串变量名 'foo'和来生成dict 'bar'

dict([(name,locals()[name]) for name in ('foo','bar')])

This is a hack. It will not work on all Python implementations distributions (in particular, those that do not have traceback.extract_stack.)

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

Note that this hack is fragile:

make_dict(bar,
          foo)

(calling make_dict on 2 lines) will not work.

Instead of trying to generate the dict out of the values foo and bar, it would be much more Pythonic to generate the dict out of the string variable names 'foo' and 'bar':

dict([(name,locals()[name]) for name in ('foo','bar')])

回答 4

在Python中这是不可能的,因为Python实际上没有“变量”。Python有名称,并且同一对象可以有多个名称。

This is not possible in Python, which really doesn’t have “variables”. Python has names, and there can be more than one name for the same object.


回答 5

我认为我的问题将有助于说明为什么这个问题很有用,并且可能会使您对如何回答这个问题有更多的了解。我编写了一个小函数来对代码中的各个变量进行快速内联头检查。基本上,它列出了变量名称,数据类型,大小和其他属性,因此我可以快速发现所犯的任何错误。代码很简单:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

因此,如果您遇到一些复杂的字典/列表/元组情况,那么让解释器返回您分配的变量名称将非常有帮助。例如,这是一个奇怪的字典:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

我不确定是否将其放在正确的位置,但是我认为这可能会有所帮助。我希望能。

I think my problem will help illustrate why this question is useful, and it may give a bit more insight into how to answer it. I wrote a small function to do a quick inline head check on various variables in my code. Basically, it lists the variable name, data type, size, and other attributes, so I can quickly catch any mistakes I’ve made. The code is simple:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

So if you have some complicated dictionary / list / tuple situation, it would be quite helpful to have the interpreter return the variable name you assigned. For instance, here is a weird dictionary:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

I’m not sure if I put this in the right place, but I thought it might help. I hope it does.


回答 6

我根据这个问题的答案写了一个简洁实用的函数。我把它放在这里以防有用。

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

用法:

>> a = 4
>> what(a)
a = 4
>>|

I wrote a neat little useful function based on the answer to this question. I’m putting it here in case it’s useful.

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

usage:

>> a = 4
>> what(a)
a = 4
>>|

回答 7

我发现,如果您已经有一个特定的值列表,则使用@S描述的方式。Lotts是最好的。但是,下面描述的方法可以很好地获取整个代码中添加的所有变量和类,而无需提供变量名,尽管您可以根据需要指定它们。可以扩展代码以排除类。

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

输出:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

I find that if you already have a specific list of values, that the way described by @S. Lotts is the best; however, the way described below works well to get all variables and Classes added throughout the code WITHOUT the need to provide variable name though you can specify them if you want. Code can be extend to exclude Classes.

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

Output:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

回答 8

在python 3中这很容易

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

这将打印:

myVariable 5

In python 3 this is easy

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

this will print:

myVariable 5


回答 9

Python3。使用inspect捕获调用本地命名空间,然后使用此处介绍的想法。正如已经指出的,可以返回多个答案。

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

Python3. Use inspect to capture the calling local namespace then use ideas presented here. Can return more than one answer as has been pointed out.

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

回答 10

这是我创建的用于读取变量名称的函数。它更通用,可以在不同的应用程序中使用:

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

要在指定问题中使用它:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

Here’s the function I created to read the variable names. It’s more general and can be used in different applications:

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

To use it in the specified question:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

回答 11

在阅读线程时,我看到了很多摩擦。给出错误答案很容易,然后让某人给出正确答案。无论如何,这就是我所发现的。

来自:[effbot.org](http://effbot.org/zone/python-objects.htm#names

名称有些不同-它们实际上不是对象的属性,并且对象本身不知道它叫什么。

一个对象可以具有任意数量的名称,也可以完全没有名称。

名称存在于命名空间中(例如模块命名空间,实例命名空间,函数的本地命名空间)。

注意:它说对象本身不知道它叫什么,所以这就是线索。Python对象不是自引用的。然后说,名称存在于命名空间中。我们在TCL / TK中有这个。所以也许我的回答会有所帮助(但确实有帮助)

    jj = 123
    打印eval(“'” + str(id(jj))+“'”)
    打印目录()

166707048
['__builtins __','__ doc __','__ file __','__ name __','__ package __','jj']

因此,列表末尾有“ jj”。

将代码重写为:

    jj = 123
    打印eval(“'” + str(id(jj))+“'”)
    对于dir()中的x:
        列印编号(eval(x))

161922920
['__builtins __','__ doc __','__ file __','__ name __','__ package __','jj']
3077447796
136515736
3077408320
3077656800
136515736
161922920

代码ID的这个讨厌的部分是变量/对象/您调用它的名字。

就是这样。当我们直接查找’jj’的内存地址时,就像在全局命名空间中查找字典时一样。我确定您可以创建一个函数来执行此操作。只要记住您的变量/对象/ wypci位于哪个命名空间即可。

QED。

In reading the thread, I saw an awful lot of friction. It’s easy enough to give a bad answer, then let someone give the correct answer. Anyway, here is what I found.

From: [effbot.org] (http://effbot.org/zone/python-objects.htm#names)

The names are a bit different — they’re not really properties of the object, and the object itself doesn’t know what it’s called.

An object can have any number of names, or no name at all.

Names live in namespaces (such as a module namespace, an instance namespace, a function’s local namespace).

Note: that it says the object itself doesn’t know what it’s called, so that was the clue. Python objects are not self-referential. Then it says, Names live in namespaces. We have this in TCL/TK. So maybe my answer will help (but it did help me)


    jj = 123
    print eval("'" + str(id(jj)) + "'")
    print dir()

166707048
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']

So there is ‘jj’ at the end of the list.

Rewrite the code as:


    jj = 123
    print eval("'" + str(id(jj)) + "'")
    for x in dir():
        print id(eval(x))

161922920
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']
3077447796
136515736
3077408320
3077656800
136515736
161922920

This nasty bit of code id’s the name of variable/object/whatever-you-pedantics-call-it.

So, there it is. The memory address of ‘jj’ is the same when we look for it directly, as when we do the dictionary look up in global name space. I’m sure you can make a function to do this. Just remember which namespace your variable/object/wypci is in.

QED.


回答 12

也许我想得太多了,但是..

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

Maybe I’m overthinking this but..

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

回答 13

import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

回答 14

我向pypi上传了一个解决方案。它是一个模块,定义了C#的等效nameof功能。

它通过字节码指令对其所调用的帧进行迭代,以获取传递给它的变量/属性的名称。该名称在找到.argreprLOAD指令下列函数的名称。

I uploaded a solution to pypi. It’s a module defining an equivalent of C#’s nameof function.

It iterates through bytecode instructions for the frame its called in, getting the names of variables/attributes passed to it. The names are found in the .argrepr of LOAD instructions following the function’s name.


回答 15

我编写了包裹法术来稳健地执行这种魔术。你可以写:

from sorcery import dict_of

my_dict = dict_of(foo, bar)

I wrote the package sorcery to do this kind of magic robustly. You can write:

from sorcery import dict_of

my_dict = dict_of(foo, bar)

回答 16

大多数对象没有__name__属性。(类,函数和模块可以使用;是否有内置类型可以包含一个?)

你会期望还有什么print(my_var.__name__)比其他print("my_var")?您可以简单地直接使用字符串吗?

您可以“切片”一个字典:

def dict_slice(D, keys, default=None):
  return dict((k, D.get(k, default)) for k in keys)

print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})

或者:

throw = object()  # sentinel
def dict_slice(D, keys, default=throw):
  def get(k):
    v = D.get(k, throw)
    if v is not throw:
      return v
    if default is throw:
      raise KeyError(k)
    return default
  return dict((k, get(k)) for k in keys)

Most objects don’t have a __name__ attribute. (Classes, functions, and modules do; any more builtin types that have one?)

What else would you expect for print(my_var.__name__) other than print("my_var")? Can you simply use the string directly?

You could “slice” a dict:

def dict_slice(D, keys, default=None):
  return dict((k, D.get(k, default)) for k in keys)

print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})

Alternatively:

throw = object()  # sentinel
def dict_slice(D, keys, default=throw):
  def get(k):
    v = D.get(k, throw)
    if v is not throw:
      return v
    if default is throw:
      raise KeyError(k)
    return default
  return dict((k, get(k)) for k in keys)

回答 17

好吧,几天前我遇到了同样的需求不得不获得一个指向对象本身的变量

为何如此必要呢?

简而言之,我正在为Maya构建一个插件。核心插件是使用C ++构建的,但GUI是通过Python绘制的(因为它不占用大量处理器)。由于我到目前为止还不知道如何return从插件中选择多个值(默认值除外)MStatus,因此要在Python中更新字典,我必须传递变量名,指向实现GUI的对象以及哪个将字典本身包含到插件中,然后使用MGlobal::executePythonCommand()来从Maya的全局范围更新字典。

要做到这一点,我所做的就是:

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

我知道这不是完美的解决方案,因为globals许多键可能指向同一个对象,例如:

a = foo()
b = a
b.name()
>>>b
or
>>>a

而且这种方法不是线程安全的。如果我错了,请纠正我。

至少这种方法解决了我的问题,方法是获取全局范围内指向对象本身的任何变量的名称,并将其作为参数传递给插件,以供内部使用。

我在int(原始整数类)上尝试过此方法,但问题是这些原始类没有被绕过(如果错误,请更正所使用的技术术语)。您可以重新实现int,然后再做,int = foo但是a = 3绝对不能成为foo原始对象的对象。要克服,你必须a = foo(3)得到a.name()工作。

Well, I encountered the very same need a few days ago and had to get a variable’s name which was pointing to the object itself.

And why was it so necessary?

In short I was building a plug-in for Maya. The core plug-in was built using C++ but the GUI is drawn through Python(as its not processor intensive). Since I, as yet, don’t know how to return multiple values from the plug-in except the default MStatus, therefore to update a dictionary in Python I had to pass the the name of the variable, pointing to the object implementing the GUI and which contained the dictionary itself, to the plug-in and then use the MGlobal::executePythonCommand() to update the dictionary from the global scope of Maya.

To do that what I did was something like:

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

I know that it is not the perfect solution in in the globals many keys could be pointing to the same object e.g.:

a = foo()
b = a
b.name()
>>>b
or
>>>a

and that the approach isn’t thread-safe. Correct me if I am wrong.

At least this approach solved my problem by getting the name of any variable in the global scope which pointed to the object itself and pass it over to the plug-in, as argument, for it use internally.

I tried this on int (the primitive integer class) but the problem is that these primitive classes don’t get bypassed (please correct the technical terminology used if its wrong). You could re-implement int and then do int = foo but a = 3 will never be an object of foo but of the primitive. To overcome that you have to a = foo(3) to get a.name() to work.


回答 18

在python 2.7和更高版本中,还具有字典理解功能,这使其变得更短了。如果可能的话,我将使用getattr代替eval(eval是邪恶的),就像在最高答案中一样。自我可以是具有您所要查看的上下文的任何对象。它可以是一个对象或locals = locals()等。

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

With python 2.7 and newer there is also dictionary comprehension which makes it a bit shorter. If possible I would use getattr instead eval (eval is evil) like in the top answer. Self can be any object which has the context your a looking at. It can be an object or locals=locals() etc.

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

回答 19

我正在研究类似的问题。@ S.Lott说:“如果有变量列表,那么“发现”它们的名字有什么意义?” 我的答案只是看它是否可以完成,以及是否出于某种原因要按类型将变量排序到列表中。所以无论如何,在我的研究中,我遇到了这个线程,并且我的解决方案有所扩展,并且基于@rlotun解决方案。@unutbu说了另一件事,“这种想法是有好处的,但是请注意,如果两个变量名引用相同的值(例如True),则可能会返回意外的变量名。” 在这个练习中,所以我处理它通过使用类似这样的可能性,每一个列表理解这是真的:isClass = [i for i in isClass if i != 'item']。没有它,“项目”将显示在每个列表中。

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

I was working on a similar problem. @S.Lott said “If you have the list of variables, what’s the point of “discovering” their names?” And my answer is just to see if it could be done and if for some reason you want to sort your variables by type into lists. So anyways, in my research I came came across this thread and my solution is a bit expanded and is based on @rlotun solution. One other thing, @unutbu said, “This idea has merit, but note that if two variable names reference the same value (e.g. True), then an unintended variable name might be returned.” In this exercise that was true so I dealt with it by using a list comprehension similar to this for each possibility: isClass = [i for i in isClass if i != 'item']. Without it “item” would show up in each list.

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

回答 20

你可以使用easydict

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

另一个例子:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

you can use easydict

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

another example:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

回答 21

在python3上,此函数将在堆栈中获得最外部的名称:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

它在代码的任何地方都很有用。遍历反向堆栈以查找第一个匹配项。

On python3, this function will get the outer most name in the stack:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

It is useful anywhere on the code. Traverses the reversed stack looking for the first match.


回答 22

尽管这可能是一个糟糕的主意,但它与rlotun的答案是一致的,但是它会更频繁地返回正确的结果。

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

您这样称呼它:

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

While this is probably an awful idea, it is along the same lines as rlotun’s answer but it’ll return the correct result more often.

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

You call it like this:

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

回答 23

应该得到列表然后返回

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

should get list then return

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

回答 24

它不会返回变量的名称,但是您可以轻松地从全局变量创建字典。

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

It will not return the name of variable but you can create dictionary from global variable easily.

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

回答 25

有了python-varname您,您可以轻松做到:

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

免责声明:我是该python-varname库的作者。

With python-varname you can easily do it:

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

Disclaimer: I’m the author of that python-varname library.


回答 26

>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

这样就可以为“ a”或“ b”获取变量名。

>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

this way get varname for a maybe ‘a’ or ‘b’.


首次使用后重新分配时,局部变量上出现UnboundLocalError

问题:首次使用后重新分配时,局部变量上出现UnboundLocalError

以下代码可在Python 2.5和3.0中正常工作:

a, b, c = (1, 2, 3)

print(a, b, c)

def test():
    print(a)
    print(b)
    print(c)    # (A)
    #c+=1       # (B)
test()

但是,当我取消注释(B)行时,我UnboundLocalError: 'c' not assigned(A)行得到了注释。的值ab被正确地打印。这使我完全困惑,原因有两个:

  1. 为什么由于行(B)的后面的语句而在行(A)抛出运行时错误?

  2. 为什么在按预期方式打印变量a并产生错误?bc

我能提出的唯一解释是,局部变量c是由赋值创建的c+=1,它c甚至在创建局部变量之前就优先于“全局”变量。当然,在变量存在之前“窃取”范围是没有意义的。

有人可以解释这种现象吗?

The following code works as expected in both Python 2.5 and 3.0:

a, b, c = (1, 2, 3)

print(a, b, c)

def test():
    print(a)
    print(b)
    print(c)    # (A)
    #c+=1       # (B)
test()

However, when I uncomment line (B), I get an UnboundLocalError: 'c' not assigned at line (A). The values of a and b are printed correctly. This has me completely baffled for two reasons:

  1. Why is there a runtime error thrown at line (A) because of a later statement on line (B)?

  2. Why are variables a and b printed as expected, while c raises an error?

The only explanation I can come up with is that a local variable c is created by the assignment c+=1, which takes precedent over the “global” variable c even before the local variable is created. Of course, it doesn’t make sense for a variable to “steal” scope before it exists.

Could someone please explain this behavior?


回答 0

Python对函数中的变量的处理方式有所不同,具体取决于您是从函数内部还是外部为其分配值。如果在函数中分配了变量,则默认情况下会将其视为局部变量。因此,当取消注释该行时,您将尝试c在分配任何值之前引用该局部变量。

如果要让变量c引用c = 3该函数之前分配的全局变量,请输入

global c

作为函数的第一行。

至于python 3,现在有

nonlocal c

您可以用来引用最近的包含c变量的封闭函数范围。

Python treats variables in functions differently depending on whether you assign values to them from inside or outside the function. If a variable is assigned within a function, it is treated by default as a local variable. Therefore, when you uncomment the line you are trying to reference the local variable c before any value has been assigned to it.

If you want the variable c to refer to the global c = 3 assigned before the function, put

global c

as the first line of the function.

As for python 3, there is now

nonlocal c

that you can use to refer to the nearest enclosing function scope that has a c variable.


回答 1

Python有点怪异之处在于,它把所有内容都保存在字典中以适应各种范围。原始的a,b,c在最高范围内,因此在该最高字典中。该函数具有其自己的字典。当到达print(a)and print(b)语句时,字典中没有该名称的任何内容,因此Python查找列表并在全局字典中找到它们。

现在我们到达c+=1,它当然等于c=c+1。当Python扫描该行时,它说:“啊哈,有一个名为c的变量,我将其放入本地范围字典中。” 然后,当它在赋值的右侧为c寻找c的值时,会找到名为c的局部变量,该变量尚无值,因此引发错误。

global c上面提到的语句只是告诉解析器它使用c全局范围内的,因此不需要一个新的语句。

它之所以说在线上存在问题,是因为它在尝试生成代码之前就在有效地寻找名称,因此从某种意义上说,它还没有真正做到这一点。我认为这是一个可用性错误,但是通常最好的做法是只学习不要过于重视编译器的消息。

如果可以的话,我可能花了一天的时间来研究和试验相同的问题,然后才发现Guido写了一些有关解释一切的字典的东西。

更新,请参阅评论:

它不会扫描代码两次,但是会在两个阶段(词法分析和解析)中扫描代码。

考虑一下这一行代码的解析方式。词法分析器读取源文本并将其分解为词素,即语法的“最小组件”。所以当它到达终点时

c+=1

它分解成类似

SYMBOL(c) OPERATOR(+=) DIGIT(1)

解析器最终希望将其放入解析树中并执行它,但是由于它是一个赋值,因此在解析树之前,它会在本地字典中查找名称c,没有看到它,然后将其插入字典中,它未初始化。用完全编译的语言,它将只进入符号表并等待解析,但是由于它没有第二遍的奢侈,因此词法分析器做了一些额外的工作以使以后的生活更轻松。仅然后,它看到操作员,看到规则说“如果您有操作员+ =,则必须已经初始化了左侧”,并说“哇!”

这里的要点是它还没有真正开始解析该行。这一切都是为实际解析做准备,因此行计数器尚未前进到下一行。因此,当它发出错误信号时,它仍会在前一行上考虑它。

正如我所说,您可能会争辩说这是一个可用性错误,但这实际上是相当普遍的事情。一些编译器对此更为诚实,并说“ XXX行或其附近的错误”,但事实并非如此。

Python is a little weird in that it keeps everything in a dictionary for the various scopes. The original a,b,c are in the uppermost scope and so in that uppermost dictionary. The function has its own dictionary. When you reach the print(a) and print(b) statements, there’s nothing by that name in the dictionary, so Python looks up the list and finds them in the global dictionary.

Now we get to c+=1, which is, of course, equivalent to c=c+1. When Python scans that line, it says “aha, there’s a variable named c, I’ll put it into my local scope dictionary.” Then when it goes looking for a value for c for the c on the right hand side of the assignment, it finds its local variable named c, which has no value yet, and so throws the error.

The statement global c mentioned above simply tells the parser that it uses the c from the global scope and so doesn’t need a new one.

The reason it says there’s an issue on the line it does is because it is effectively looking for the names before it tries to generate code, and so in some sense doesn’t think it’s really doing that line yet. I’d argue that is a usability bug, but it’s generally a good practice to just learn not to take a compiler’s messages too seriously.

If it’s any comfort, I spent probably a day digging and experimenting with this same issue before I found something Guido had written about the dictionaries that Explained Everything.

Update, see comments:

It doesn’t scan the code twice, but it does scan the code in two phases, lexing and parsing.

Consider how the parse of this line of code works. The lexer reads the source text and breaks it into lexemes, the “smallest components” of the grammar. So when it hits the line

c+=1

it breaks it up into something like

SYMBOL(c) OPERATOR(+=) DIGIT(1)

The parser eventually wants to make this into a parse tree and execute it, but since it’s an assignment, before it does, it looks for the name c in the local dictionary, doesn’t see it, and inserts it in the dictionary, marking it as uninitialized. In a fully compiled language, it would just go into the symbol table and wait for the parse, but since it WON’T have the luxury of a second pass, the lexer does a little extra work to make life easier later on. Only, then it sees the OPERATOR, sees that the rules say “if you have an operator += the left hand side must have been initialized” and says “whoops!”

The point here is that it hasn’t really started the parse of the line yet. This is all happening sort of preparatory to the actual parse, so the line counter hasn’t advanced to the next line. Thus when it signals the error, it still thinks its on the previous line.

As I say, you could argue it’s a usability bug, but its actually a fairly common thing. Some compilers are more honest about it and say “error on or around line XXX”, but this one doesn’t.


回答 2

看一下反汇编可以澄清正在发生的事情:

>>> def f():
...    print a
...    print b
...    a = 1

>>> import dis
>>> dis.dis(f)

  2           0 LOAD_FAST                0 (a)
              3 PRINT_ITEM
              4 PRINT_NEWLINE

  3           5 LOAD_GLOBAL              0 (b)
              8 PRINT_ITEM
              9 PRINT_NEWLINE

  4          10 LOAD_CONST               1 (1)
             13 STORE_FAST               0 (a)
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE

如您所见,访问a的字节码是LOAD_FAST,访问b 的字节码LOAD_GLOBAL。这是因为编译器已经确定在函数内已将a分配给它,并将其归类为局部变量。局部变量的访问机制与全局变量的根本不同-它们在帧的变量表中静态分配了一个偏移量,这意味着查找是一个快速索引,而不是全局变量更昂贵的dict查找。因此,Python将print a行读为“获取插槽0中保存的局部变量’a’的值,并打印出来”,并且当它检测到该变量仍未初始化时,将引发异常。

Taking a look at the disassembly may clarify what is happening:

>>> def f():
...    print a
...    print b
...    a = 1

>>> import dis
>>> dis.dis(f)

  2           0 LOAD_FAST                0 (a)
              3 PRINT_ITEM
              4 PRINT_NEWLINE

  3           5 LOAD_GLOBAL              0 (b)
              8 PRINT_ITEM
              9 PRINT_NEWLINE

  4          10 LOAD_CONST               1 (1)
             13 STORE_FAST               0 (a)
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE

As you can see, the bytecode for accessing a is LOAD_FAST, and for b, LOAD_GLOBAL. This is because the compiler has identified that a is assigned to within the function, and classified it as a local variable. The access mechanism for locals is fundamentally different for globals – they are statically assigned an offset in the frame’s variables table, meaning lookup is a quick index, rather than the more expensive dict lookup as for globals. Because of this, Python is reading the print a line as “get the value of local variable ‘a’ held in slot 0, and print it”, and when it detects that this variable is still uninitialised, raises an exception.


回答 3

当您尝试传统的全局变量语义时,Python具有相当有趣的行为。我不记得详细信息,但是您可以很好地读取在“全局”范围内声明的变量的值,但是如果要修改它,则必须使用global关键字。尝试更改test()为此:

def test():
    global c
    print(a)
    print(b)
    print(c)    # (A)
    c+=1        # (B)

另外,出现此错误的原因是因为您还可以在该函数内声明一个新变量,其名称与“全局”变量相同,因此它将是完全独立的。解释器认为您正在尝试在此范围内创建一个新变量,c并在一个操作中对其进行全部修改,这在Python中是不允许的,因为c未初始化此新变量。

Python has rather interesting behavior when you try traditional global variable semantics. I don’t remember the details, but you can read the value of a variable declared in ‘global’ scope just fine, but if you want to modify it, you have to use the global keyword. Try changing test() to this:

def test():
    global c
    print(a)
    print(b)
    print(c)    # (A)
    c+=1        # (B)

Also, the reason you are getting this error is because you can also declare a new variable inside that function with the same name as a ‘global’ one, and it would be completely separate. The interpreter thinks you are trying to make a new variable in this scope called c and modify it all in one operation, which isn’t allowed in Python because this new c wasn’t initialized.


回答 4

清楚说明的最佳示例是:

bar = 42
def foo():
    print bar
    if False:
        bar = 0

在调用时foo(),尽管我们永远都不会到达line ,但这也会引发问题 ,因此从逻辑上讲,绝对不应创建局部变量。UnboundLocalErrorbar=0

神秘之处在于“ Python是一种解释性语言 ”,并且函数的声明foo被解释为单个语句(即复合语句),它只是笨拙地解释它并创建局部和全局作用域。因此bar在执行之前会在本地范围内被识别。

有关此类的更多示例,请阅读以下文章:http : //blog.amir.rachum.com/blog/2013/07/09/python-common-newbie-mistakes-part-2/

这篇文章提供了Python变量作用域的完整说明和分析:

The best example that makes it clear is:

bar = 42
def foo():
    print bar
    if False:
        bar = 0

when calling foo() , this also raises UnboundLocalError although we will never reach to line bar=0, so logically local variable should never be created.

The mystery lies in “Python is an Interpreted Language” and the declaration of the function foo is interpreted as a single statement (i.e. a compound statement), it just interprets it dumbly and creates local and global scopes. So bar is recognized in local scope before execution.

For more examples like this Read this post: http://blog.amir.rachum.com/blog/2013/07/09/python-common-newbie-mistakes-part-2/

This post provides a Complete Description and Analyses of the Python Scoping of variables:


回答 5

这里有两个链接可能会有所帮助

1:当变量具有值时,docs.python.org / 3.1 / faq / programming.html?highlight = nonlocal#why-am-i-getting-unboundboundlocalerror-

2:docs.python.org/3.1/faq/programming.html?highlight = nonlocal#how-do-i-write-a-function-with-output-parameters-call by reference

链接一描述了错误UnboundLocalError。链接二可以帮助您重写测试功能。根据链接二,原始问题可以重写为:

>>> a, b, c = (1, 2, 3)
>>> print (a, b, c)
(1, 2, 3)
>>> def test (a, b, c):
...     print (a)
...     print (b)
...     print (c)
...     c += 1
...     return a, b, c
...
>>> a, b, c = test (a, b, c)
1
2
3
>>> print (a, b ,c)
(1, 2, 4)

Here are two links that may help

1: docs.python.org/3.1/faq/programming.html?highlight=nonlocal#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value

2: docs.python.org/3.1/faq/programming.html?highlight=nonlocal#how-do-i-write-a-function-with-output-parameters-call-by-reference

link one describes the error UnboundLocalError. Link two can help with with re-writing your test function. Based on link two, the original problem could be rewritten as:

>>> a, b, c = (1, 2, 3)
>>> print (a, b, c)
(1, 2, 3)
>>> def test (a, b, c):
...     print (a)
...     print (b)
...     print (c)
...     c += 1
...     return a, b, c
...
>>> a, b, c = test (a, b, c)
1
2
3
>>> print (a, b ,c)
(1, 2, 4)

回答 6

这不是您问题的直接答案,而是紧密相关的,因为这是由扩展分配和函数作用域之间的关系引起的另一个难题。

在大多数情况下,您倾向于认为扩充分配(a += b)与简单分配(a = a + b)完全等效。不过,在一个极端的情况下,可能会遇到一些麻烦。让我解释:

Python的简单分配的工作方式意味着,如果a将其传递到函数中(如func(a);请注意,Python始终是按引用传递),则a = a + b不会修改所a传递的。相反,它将仅修改的本地指针a

但是,如果使用a += b,则有时可以实现为:

a = a + b

或有时(如果该方法存在)为:

a.__iadd__(b)

在第一种情况下(只要a未声明为全局),局部作用域之外就没有副作用,因为对的赋值a只是指针更新。

在第二种情况下,a实际上将修改自身,因此对的所有引用都a将指向修改后的版本。以下代码演示了这一点:

def copy_on_write(a):
      a = a + a
def inplace_add(a):
      a += a
a = [1]
copy_on_write(a)
print a # [1]
inplace_add(a)
print a # [1, 1]
b = 1
copy_on_write(b)
print b # [1]
inplace_add(b)
print b # 1

因此,诀窍是避免在函数参数上增加分配(我尝试仅将其用于局部/循环变量)。使用简单的分配,您就可以避免歧义行为。

This is not a direct answer to your question, but it is closely related, as it’s another gotcha caused by the relationship between augmented assignment and function scopes.

In most cases, you tend to think of augmented assignment (a += b) as exactly equivalent to simple assignment (a = a + b). It is possible to get into some trouble with this though, in one corner case. Let me explain:

The way Python’s simple assignment works means that if a is passed into a function (like func(a); note that Python is always pass-by-reference), then a = a + b will not modify the a that is passed in. Instead, it will just modify the local pointer to a.

But if you use a += b, then it is sometimes implemented as:

a = a + b

or sometimes (if the method exists) as:

a.__iadd__(b)

In the first case (as long as a is not declared global), there are no side-effects outside local scope, as the assignment to a is just a pointer update.

In the second case, a will actually modify itself, so all references to a will point to the modified version. This is demonstrated by the following code:

def copy_on_write(a):
      a = a + a
def inplace_add(a):
      a += a
a = [1]
copy_on_write(a)
print a # [1]
inplace_add(a)
print a # [1, 1]
b = 1
copy_on_write(b)
print b # [1]
inplace_add(b)
print b # 1

So the trick is to avoid augmented assignment on function arguments (I try to only use it for local/loop variables). Use simple assignment, and you will be safe from ambiguous behaviour.


回答 7

Python解释器将读取一个函数作为一个完整的单元。我认为它是通过两次读取来读取的,一次是收集其闭包(局部变量),另一次是将其转换为字节码。

如您所知,您可能已经知道,在’=’左边使用的任何名称都隐含一个局部变量。我不止一次地通过将变量访问更改为+ =被发现,这突然是一个不同的变量。

我还想指出,这实际上与全局范围无关。嵌套函数具有相同的行为。

The Python interpreter will read a function as a complete unit. I think of it as reading it in two passes, once to gather its closure (the local variables), then again to turn it into byte-code.

As I’m sure you were already aware, any name used on the left of a ‘=’ is implicitly a local variable. More than once I’ve been caught out by changing a variable access to a += and it’s suddenly a different variable.

I also wanted to point out it’s not really anything to do with global scope specifically. You get the same behaviour with nested functions.


回答 8

c+=1Assigns c,python假定已分配的变量是局部变量,但在这种情况下,尚未在本地声明。

使用globalnonlocal关键字。

nonlocal 仅在python 3中有效,因此,如果您使用的是python 2,并且不想将变量设置为全局变量,则可以使用可变对象:

my_variables = { # a mutable object
    'c': 3
}

def test():
    my_variables['c'] +=1

test()

c+=1 assigns c, python assumes assigned variables are local, but in this case it hasn’t been declared locally.

Either use the global or nonlocal keywords.

nonlocal works only in python 3, so if you’re using python 2 and don’t want to make your variable global, you can use a mutable object:

my_variables = { # a mutable object
    'c': 3
}

def test():
    my_variables['c'] +=1

test()

回答 9

到达类变量的最佳方法是直接通过类名称访问

class Employee:
    counter=0

    def __init__(self):
        Employee.counter+=1

The best way to reach class variable is directly accesing by class name

class Employee:
    counter=0

    def __init__(self):
        Employee.counter+=1

回答 10

在python中,对于所有类型的变量,局部变量,类变量和全局变量,我们都有类似的声明。当您从方法引用全局变量时,python认为您实际上是在从方法本身引用变量,而该变量尚未定义,因此会引发错误。要引用全局变量,我们必须使用globals()[‘variableName’]。

在您的情况下,请分别使用globals()[‘a],globals()[‘b’]和globals()[‘c’]代替a,b和c。

In Python we have similar declaration for all type of variables: local, class, and global variables. When you refer to a global variable from a method, Python thinks that you are actually referring to a variable from the method itself, which is not yet defined and hence it throws an error.

To refer global variable we have to use globals()['variableName'].

in your case use globals()['a], globals()['b'] and globals()['c'] instead of a,b and c respectively.


回答 11

同样的问题困扰着我。使用nonlocalglobal可以解决问题。
但是,使用时需要注意nonlocal,它适用于嵌套函数。但是,在模块级别,它不起作用。在此处查看示例

The same problem bothers me. Using nonlocal and global can solve the problem.
However, attention needed for the usage of nonlocal, it works for nested functions. However, in a module level, it does not work. See examples here.