是否只能在Python中声明变量而不分配任何值?


288

是否可以像这样在Python中声明变量?

var

以便将其初始化为None?似乎Python允许这样做,但是一旦您访问它,它就会崩溃。这可能吗?如果没有,为什么?

编辑:我想这样做的情况下:

value

for index in sequence:

   if value == None and conditionMet:
       value = index
       break

重复

有关


1
可以发布一个导致该问题的小程序。
Preet Sangha,2009年

您发布了一个重复的问题,并投票赞成关闭该问题,以另一个问题胜诉。
杰鲁布(Jerub)2009年

仍然存在一些差异,这涉及仅通过声明就无法使用变量的问题。
Joan Venge

正如您的第一个问题所说明的那样,在python世界中实际上没有任何声明变量的事情。
哈雷·霍尔科姆

1
为什么没有人说“只是分配给它”,因为在将变量分配给期间之前不存在变量。并且python中的变量不包含类型信息。对象这样做。变量仅用于保留该时间点的对象。此外,上面的程序应在第一行上引发NameError异常。(这就是我在2.X和3.X中都得到的结果)
osirisgothra

Answers:


359

为什么不这样做:

var = None

Python是动态的,因此您无需声明任何东西。它们自动存在于分配它们的第一个范围中。因此,您只需要一个如上所述的常规旧赋值语句即可。

很好,因为您永远不会以未初始化的变量结尾。但是要小心-这并不意味着您最终不会得到错误初始化的变量。如果您将初始化为None,请确保这是您真正想要的,并尽可能分配更有意义的内容。


1
我本来打算那样做,但是只是隐含地认为这样做会做。
Joan Venge

7
关键是要明确,而不要隐含。不知道初始值是多少。难怪未初始化的变量会引发异常或具有神奇的价值。
S.Lott

2
我唯一遇到的问题是,我一直在跟踪一个计数器(minValue),并且每当一个值小于它时,我就将其设置为新的minValue。如果我最初将minValue声明为None,那么显然它仍然比我与之比较的任何数字都要低。我最终只是在sys.maxint上进行了初始化
TJ Biddle

...它们自动存在于分配它们的第一个范围中。因此,您必须找出第一个任务并弄清楚。啊!
Ed Randall

56

我衷心建议您阅读其他语言的“变量”(我将其添加为相关链接)–在两分钟内,您将知道Python具有“名称”,而不是“变量”。

val = None
# ...
if val is None:
   val = any_object

您也可以编写val = val or any_object初始化它。
佐尔坦

1
@Zoltán:如果val的有效值是“ false”(例如零或空),则会中断。使用is测试值是否为None
jfs

在提供的链接上阅读了该文章之后,似乎只不过是语义上的诡辩。
Andrew P.

28

在Python 3.6+中,您可以为此使用变量注释:

https://www.python.org/dev/peps/pep-0526/#abstract

PEP 484引入了类型提示,也就是类型注释。尽管它的主要焦点是函数注释,但它也引入了类型注释的概念来注释变量:

# 'captain' is a string (Note: initial value is a problem)
captain = ...  # type: str

PEP 526旨在向Python添加语法来注释变量的类型(包括类变量和实例变量),而不是通过注释来表示它们:

captain: str  # Note: no initial value!

似乎更符合您的要求:“是否有可能只声明变量而不在Python中分配任何值?”


2
出色答卷

16

我不确定您要做什么。Python是一种非常动态的语言。在实际分配或使用变量之前,通常不需要声明变量。我想你要做的就是

foo = None

它将把值None赋给变量foo

编辑:您似乎真正想做的就是:

#note how I don't do *anything* with value here
#we can just start using it right inside the loop

for index in sequence:
   if conditionMet:
       value = index
       break

try:
    doSomething(value)
except NameError:
    print "Didn't find anything"

从如此简短的代码示例中很难分辨出这是否是正确的样式,但这一种更加“ Pythonic”的工作方式。

编辑:以下是JFS的注释(发布在此处以显示代码)

与OP的问题无关,但以上代码可以重写为:

for item in sequence:
    if some_condition(item): 
       found = True
       break
else: # no break or len(sequence) == 0
    found = False

if found:
   do_something(item)

注意:如果some_condition()引发异常,则found没有约束。
注意:如果len(sequence)== 0,则item表示未绑定。

上面的代码不建议使用。其目的是说明局部变量的工作方式,即在这种情况下只能在运行时确定“变量”是否为“定义”。首选方式:

for item in sequence:
    if some_condition(item):
       do_something(item)
       break

要么

found = False
for item in sequence:
    if some_condition(item):
       found = True
       break

if found:
   do_something(item)

动态语言和动态语言之间有区别吗?
加文·米勒

有一篇很棒的文章解释了编程语言键入的不同轴,以及它们如何是连续体,而不是布尔值。不幸的是,当我想引用它时,我再也找不到该文章了:(我认为Python是“非常动态的”,因为它位于多轴的远端
。– kquinn

3

我通常将变量初始化为某种表示类型的东西

var = ""

要么

var = 0

如果它将成为对象,那么在实例化它之前不要对其进行初始化:

var = Var()

3

好吧,如果您想检查是否定义了变量,那为什么不检查它是否在locals()或globals()数组中呢?您的代码被重写:

for index in sequence:
   if 'value' not in globals() and conditionMet:
       value = index
       break

如果它是您要查找的局部变量,则将locals()替换为globals()。


2

首先,我对您最初提出的问题的回答

问:如何查找是否在代码中的某个点定义了变量?

答:在源文件中读取,直到看到定义该变量的行。

但是,此外,您还给出了一个代码示例,其中的各种排列都是pythonic的。您正在寻找一种扫描序列以查找与条件匹配的元素的方法,因此这里有一些解决方案:

def findFirstMatch(sequence):
    for value in sequence:
        if matchCondition(value):
            return value

    raise LookupError("Could not find match in sequence")

显然,在此示例中,您可以根据要实现的目标raise用替换return None

如果您想要满足条件的所有内容,则可以执行以下操作:

def findAllMatches(sequence):
    matches = []
    for value in sequence:
        if matchCondition(value):
            matches.append(value)

    return matches

还有另一种方法yield,我不会麻烦您看,因为它的工作方式非常复杂。

此外,有一种方法可以实现此目的:

all_matches = [value for value in sequence if matchCondition(value)]

2

如果我理解您的示例正确,那么无论如何您都无需在if语句中引用“值”。只要将其设置为任何值,您就可以摆脱循环。

value = None
for index in sequence:
   doSomethingHere
   if conditionMet:
       value = index
       break 

1

您似乎正在尝试用Python编写C。如果您想按顺序查找某物,Python提供了内置函数来实现,例如

value = sequence.index(blarg)

1

这是一个好问题,不幸的var = None是,答案很差,因为已经分配了一个值,并且如果您的脚本多次运行,则None每次都会覆盖它。

它与没有分配的定义不同。我仍在尝试找出如何绕过此问题的方法。


1

是否可以在Python中声明变量(var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var

0
var_str = str()
var_int = int()

顽皮的顽皮的顽皮男人!变量不关联类型,对象关联。不应将var_str限制为此类通用名称。如果要执行此操作,则使其变得有意义,例如“ var_age”或“ var_name”。这样的值可以作为整数或字符串或任何您想要的值,然后更改为对象,正是python与其他语言不同的本质。他们说,如果您发现自己一直需要这样做,则可能要使用其他语言。
osirisgothra 2015年


0

您可以使用此丑陋的oneliner欺骗解释器。if None: var = None 除了将变量添加var到局部变量字典中而不进行初始化之外,它什么也没做。如果您随后尝试在函数中使用此变量,则解释器将引发UnboundLocalError异常。这也适用于非常古老的python版本。不简单,也不漂亮,但是不要对python有太多期望。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.