【问题标题】:Is it possible only to declare a variable without assigning any value in Python?是否可以只声明一个变量而不在 Python 中分配任何值?
【发布时间】:2010-10-14 10:31:47
【问题描述】:

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

var

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

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

value

for index in sequence:

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

复制

相关

【问题讨论】:

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

标签: python variable-assignment variable-declaration


【解决方案1】:

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

uninitialized_value:str

# some code logic

uninitialized_value = "Value"

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

uninitialized_value:str

# some code logic

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        PEP 484 引入了类型提示,也就是类型注释。虽然它的主要重点是函数注释,但它还引入了类型 cmets 的概念来注释变量:

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

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

        captain: str  # Note: no initial value!
        

        这似乎更直接地符合您所问的“是否可以只声明一个变量而不在 Python 中分配任何值?”

        【讨论】:

        • 优秀的答案
        • 应该是公认的答案(在 Python 的进化阶段等)
        【解决方案5】:

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

        var = object()
        

        这个哨兵是Nick Coghlan建议的。

        【讨论】:

          【解决方案6】:

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

          这与没有赋值的定义不同。我还在想办法绕过这个问题。

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

            • 你也可以写val = val or any_object来初始化它。
            • @Zoltán:如果 val 的有效值为“false”,例如零或空,它会中断。使用is测试一个值是否为None
            • 在阅读提供的链接上的文章后,它似乎只是语义上的诡辩。
            【解决方案8】:
            var_str = str()
            var_int = int()
            

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                【解决方案10】:

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

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

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

                【讨论】:

                  【解决方案11】:

                  我不确定你想做什么。 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 “非常动态”,因为它位于多个轴的远端。
                  【解决方案12】:

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

                  value = sequence.index(blarg)
                  

                  【讨论】:

                    【解决方案13】:

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

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

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

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

                    【讨论】:

                      【解决方案14】:

                      为什么不这样做:

                      var = None
                      

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

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

                      【讨论】:

                      • 我本来打算那样做的,但只是隐含地认为它会那样做。
                      • 重点是明确的,而不是隐含的。不用猜测初始值是多少。不知道未初始化的变量是否会引发异常或神奇地具有有用的值。
                      • 我遇到的唯一问题是我一直在跟踪一个计数器 (minValue),每当某个值低于它时,我都会将其设置为新的 minValue。如果我最初将 minValue 声明为 None,那么显然它仍然低于我与之比较的任何数字。我最终只是在 sys.maxint 初始化它
                      • ...它们自动存在于分配它们的第一个作用域中。所以,你必须找到第一个任务并弄清楚。啊!
                      【解决方案15】:

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

                      var = ""
                      

                      var = 0
                      

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

                      var = Var()
                      

                      【讨论】:

                        猜你喜欢
                        • 2011-08-19
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-11-26
                        • 2011-03-16
                        相关资源
                        最近更新 更多