【问题标题】:Function Returning a NoneType in Python?在 Python 中返回 NoneType 的函数?
【发布时间】:2013-11-01 01:41:41
【问题描述】:

在为 CS1 开发 Python 项目时,我遇到了一个我和我的室友都无法解决的奇怪问题。代码的一般范围是使用数字填充具有一定大小形状的 0 网格来填充空间,并且我们必须一路检查以确保我们没有将形状放在已经有形状的地方。我在这里有两个函数,它们几乎都做同样的事情,但无论出于何种原因,当 falsechecker 返回列表时,它会将其作为 NoneType 返回。为什么会这样?

def falseChecker(binList, r, c, size):
    sCheck = isSpaceFree(binList, r, c, size)
    if sCheck == True:
        for x in range(c, c+size):
            for y in range(r, r+size):
                binList[x][y] = size
        return binList
    else:
        c += 1
        if c > len(binList):
            c = 0
            r += 1
            if r > len(binList):
                return binList
        falseChecker(binList, r, c, size)





def iChecker(binList, blockList):
    r = 0
    c = 0
    for i in blockList:
        check = isSpaceFree(binList, r, c, i)
        if check == True:
            for x in range(c, c+i):
                for y in range(r, r+i):
                    binList[x][y] = i
            c += 1
            if c > len(binList):
                c = 0
                r += 1
                if r > len(binList):
                    return binList
        else:
            binList = falseChecker(binList, r, c, i)

    return binList

main()

【问题讨论】:

  • @Everybody:对于常见的“我写了一个递归函数,但没有从其中一个递归调用返回值”问题,是否存在规范重复?
  • 附带说明,if sCheck: 在几乎所有情况下都比if sCheck == True: 好(包括这种情况)。
  • @abarnert“几乎”?是否有任何情况首选== True
  • @lvc:曾几何时,我使用了一个设计糟糕的包,该包包含一个 C 库,其中包含返回 True 表示成功但返回负整数错误代码表示失败的函数。我编写了一个模块来包装所有调用并检查 == True 否则引发了一个异常,以从我的代码的其余部分隐藏可怕的 API,并在注释中解释它在做什么,并提交了一个针对包裹。 (如果你很好奇,上游修复是返回一个 True 或 False 和 0 或负错误代码的元组,这稍微不那么可怕......)

标签: python function nonetype


【解决方案1】:

sCheck == True 为假的情况下,您不需要return 任何东西。而在 Python 中,一个没有明确地 return 的函数会返回 None

如果您尝试递归调用自己并返回结果,您需要这样:

return falseChecker(binList, r, c, size)

【讨论】:

    【解决方案2】:

    递归行:

    falseChecker(binList, r, c, size)
    

    需要

    return falseChecker(binList, r, c, size)
    

    或者递归函数结束,并且外部函数继续运行,因为它还没有返回。然后它完成而不返回,因此返回None

    【讨论】:

      【解决方案3】:

      falseChecker 末尾需要一个return

      def falseChecker(binList, r, c, size):
          sCheck = isSpaceFree(binList, r, c, size)
          if sCheck == True:
              for x in range(c, c+size):
                  for y in range(r, r+size):
                      binList[x][y] = size
              return binList
          else:
              c += 1
              if c > len(binList):
                  c = 0
                  r += 1
                  if r > len(binList):
                       return binList
      
              #################################
              return falseChecker(binList, r, c, size)
              #################################
      

      在 Python 中,如果函数结束而没有返回,则默认返回 None。此外,当falseChecker第一次运行时,如果sCheckFalse,那么它将执行else块。此代码块不包含 return。因此,falseChecker 的最终返回值将是None

      【讨论】:

        【解决方案4】:

        我也有同样的想法,做了一些超出我职责的练习 =),我修改了一些代码来学习如何使用装饰器:

        def listPrime(f):    #list the prime numbers
            def wrapper(x):
                for n in range(x):
                    if f(n):
                        print(n, end = " ", flush=True)
                print()
        
        @listPrime
        def isprime(n = 0): #evaluate when a number is prime (true) or isn't
            if n<=1:
                return False
            for x in range(2,n):
                if n % x == 0:
                    return False
            else:
                return True
        
        isprime(100)  
        

        但在这种情况下,控制台向我抛出了这个错误“TypeError:'NoneType'对象不可调用”,在这种情况下打印对象(函数)isprime()的类型,它说它实际上是一个,但是当我删除 @listPrime 装饰器时,此状态更改为 。这是为什么呢?

        我知道还有另一种形式可以运行代码:

        def isprime(n):
            if n<=1:
                return False
            for x in range(2,n):
                if n % x == 0:
                    return False
            else:
                return True
        
        def listPrime(x):    #lista numeros primos
            for n in range(x):
                if isprime(n):
                    print(n, end = " ", flush=True)
            print()
        
        listPrime(200)
        

        但我尝试修改它是为了学习如何使用装饰器。

        【讨论】:

        • 好的,我通过返回 listPrime 函数 "return wrapper" 来做到这一点。但我仍然不明白为什么 isprime 的类型会随着装饰器而改变。
        猜你喜欢
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-29
        • 2021-05-13
        • 2019-05-10
        • 1970-01-01
        相关资源
        最近更新 更多