ChatGPT解决这个技术问题 Extra ChatGPT

是否可以只声明一个变量而不在 Python 中分配任何值?

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

var

使其初始化为无?似乎 Python 允许这样做,但是一旦您访问它,它就会崩溃。这可能吗?如果不是,为什么?

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

value

for index in sequence:

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

相关问题

为什么函数可以修改调用者感知的某些参数,而不能修改其他参数?

Python 变量声明

也可以看看

Python 名称和值

其他语言有“变量”

您发布了一个重复的问题,投票结束此问题以支持另一个问题。
仍然有一些区别,这个处理不能通过声明来使用变量。
正如您的第一个问题所解释的那样,在 python 世界中并没有真正声明变量之类的东西。
为什么没有人说“只是分配给它”,因为变量在分配给期间之前不存在。 python中的变量不包含类型信息。对象就是这样做的。变量仅用于在该时间点保存对象。此外,上面的程序应该在第一行抛出一个 NameError 异常。 (这就是我在 2.X 和 3.X 中得到的)

T
Todd Gamblin

为什么不这样做:

var = None

Python是动态的,所以你不需要声明东西;它们自动存在于分配它们的第一个范围内。因此,您所需要的只是上面的常规旧赋值语句。

这很好,因为你永远不会得到一个未初始化的变量。但是要小心——这并不意味着你不会得到不正确初始化的变量。如果您为 None 初始化某些内容,请确保这是您真正想要的,并尽可能分配更有意义的内容。


我打算这样做,但只是隐含地认为它会那样做。
关键是这是明确的,而不是隐含的。不用猜测初始值是多少。不用怀疑未初始化的变量是否会引发异常或神奇地具有有用的值。
我唯一遇到的问题是我一直在跟踪一个计数器(minValue),只要一个值低于它,我就将它设置为新的 minValue。如果我最初将 minValue 声明为 None,那么显然它仍然低于我与之比较的任何数字。我最终只是在 sys.maxint 初始化它
...它们自动存在于分配它们的第一个范围内。所以,你必须找到第一个任务并弄清楚。啊!
“NoneType”对象不可下标
T
Tagar

在 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 中分配任何值?”

注意:Python 运行时不强制执行函数和变量类型注释。它们可以被第三方工具使用,例如类型检查器、IDE、linter 等。


应该是公认的答案(此时在 Python 的演变等方面)
重新“注意:没有初始值!”:它实际上也没有创建变量。在分配值之前尝试访问 captain 将导致与其他情况下相同的 NameError。另一方面,代码也没有对可以分配的内容施加任何限制。 captain: str 之类的代码虽然在 3.6 及更高版本中有效,但在 Python 本身中无效;它可能被第三方类型检查工具使用。
@KarlKnechtel 是的,这是在 PEP 526 中提到的,我添加了该注释,谢谢
j
jfs

我衷心建议您阅读 Other languages have "variables"(我将其添加为相关链接)——在两分钟内您就会知道 Python 有“名称”,而不是“变量”。

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

您也可以编写 val = val or any_object 来初始化它。
@Zoltán:如果 val 的有效值为“假”,例如零或空,它会中断。使用 is 测试值是否为 None
在提供的链接上阅读文章后,它似乎只是语义上的诡辩。
@AndrewP .:不要这么轻易地忽略它。这些年来,我坚持我的建议。 “nametag -> balloon”模型非常简单,同时它很好地描述了 Python 中的名称绑定行为。
j
jfs

我不确定你想做什么。 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 “非常动态”,因为它位于多个轴的远端。
J
Johan

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

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

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


A
Andrew Hare

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

var = ""

或者

var = 0

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

var = Var()

J
Jerub

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

问:如何发现变量是否在我的代码中的某个点定义?

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

但更进一步,您已经给出了一个代码示例,其中有各种非常 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)]

P
Peter

如果我正确理解了您的示例,则无论如何您都不需要在 if 语句中引用“值”。只要可以将其设置为任何内容,您就会跳出循环。

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

佚名

您看起来像是在尝试用 Python 编写 C。如果你想在一个序列中找到一些东西,Python 有内置函数可以做到这一点,比如

value = sequence.index(blarg)

M
Martin Evans

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

它与没有赋值的定义不同。我仍在试图弄清楚如何绕过这个问题。


C
Chris_Rands

如果 None 是一个有效的数据值,那么您需要以另一种方式访问该变量。你可以使用:

var = object()

此哨兵由 Nick Coghlan 建议。


P
Pasha

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

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

E
Ekure Edem

我知道它来晚了,但使用 python3,你可以通过使用声明一个未初始化的值

uninitialized_value:str

# some code logic

uninitialized_value = "Value"

但是要非常小心这个技巧,因为

uninitialized_value:str

# some code logic

# WILL NOT WORK
uninitialized_value += "Extra value\n"

R
Rory McCrossan
var_str = str()
var_int = int()

Z
ZAB

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