返回Python函数之外的计数器

时间:2013-08-29 21:48:59

标签: python counter

我正在尝试构建一些代码,并且我已经定义了一个函数,以测试计数器在函数内部的工作方式:

def errorPrinting(x):
    x += 1
    return x

然后我在某些条件逻辑中使用该函数,我希望在满足条件时计数器增加。

x = 1

for row in arcpy.SearchCursor(fc):              

    if not row.INCLUSION_TYPE or len(row.TYPE.strip()) == 0:
        errorPrinting(x)
        print x

    elif len(row.TYPE) not in range(2,5):
        errorPrinting(x)
        print x

    elif row.INCLUSION_TYPE.upper() not in [y.upper() for y in TableList]:
        errorPrinting(x)
        print x

我仍然使用函数相当新,所以也许我不理解如何将值返回到函数之外,以便在for循环的下一次迭代中使用。它一直在我身上回归。任何人都可以告诉我如何在函数增加一个x + = 1之后将x返回到函数之外吗?

谢谢, 麦克

4 个答案:

答案 0 :(得分:3)

你的范围很大。您可以查看此link以获得快速入门。

你可以做一些简单的事情,并且在你调用errorPrinting并得到你想要的所有情况下说x = errorPrinting(x)。但我认为有更好的解决方案可以让您了解更多信息。

考虑实现一个为您维护计数的错误记录器对象。然后你可以做logger.errorPrinting(),你的logger实例将管理计数器。您可能还想查看python' built in logging facilities

答案 1 :(得分:3)

你没有递增你的全局x,你正在递增当地的参数,也就是恰好命名为x! (您对errorPrinting的参数可能已被命名为任何内容。我称之为xLocal。)

正如您在此处所见,x不会被函数递增。

>>> def inc(xLocal):
...     xLocal += 1
...     return xLocal
... 
>>> x = 4
>>> inc(x)
5
>>> x
4

每次都需要将x的值重新分配给函数的返回值。喜欢这个

x = 1
for row in arcpy.SearchCursor(fc):              

    if not row.INCLUSION_TYPE or len(row.TYPE.strip()) == 0:
        x = errorPrinting(x) # <=== here
        print x

    elif len(row.TYPE) not in range(2,5):
        x = errorPrinting(x) # <=== here
        print x

    elif row.INCLUSION_TYPE.upper() not in [y.upper() for y in TableList]:
        x = errorPrinting(x) # <=== here
        print x

Integral参数和其他基元通常不会在Python中通过引用传递。 (列表,dicts等等。无意中修改列表实际上是Python中常见的错误。)

编辑:通过“引用”和“值”传递在Python中谈论并不正确。有关更多详细信息,请参阅this不错的问题。

所以,使用我之前的例子:

>>> x = 4
>>> x = inc(x)
>>> x
5

请注意,如果这是通过引用传递的参数(如列表),则此策略可行。

>>> def incList(xList):
...     for i in range(len(xList)):
...         xList[i] += 1
... 
>>> xList
[1]
>>> incList(xList)
>>> xList
[2]

注意普通的Pythonic语法:

for i in xList:
    i += 1

不会增加全局值。

注意:如果您希望密切关注很多事情,我还建议使用logging模块@SB。提及。它非常有用,可以更轻松地调试大型程序。你可以得到时间,消息类型等。

答案 2 :(得分:2)

编辑OP的好处,因为如果函数是一个新概念,我之前的评论可能有点难以理解。

我个人认为解决此问题的最佳方法是将相关代码包装在对象中。

Python主要基于对象的概念,您可以将其视为使用对该数据进行操作的函数对数据进行分组。一个对象可能代表一个东西,或者在某些情况下可能只是让一些相关函数共享一些数据的便捷方式。

对象定义为“类”,它定义对象的类型,然后创建“实例”,每个实例都是类中定义的数据分组的单独副本。

class MyPrint(object):

    def __init__(self):
        self.x = 1

    def errorPrinting(self):
        self.x += 1
        return self.x

    def myPrint(self):
        for row in arcpy.SearchCursor(fc):              

            if not row.INCLUSION_TYPE or len(row.TYPE.strip()) == 0:
                self.errorPrinting()
                print self.x

            elif len(row.TYPE) not in range(2,5):
                self.errorPrinting()
                print self.x

            elif row.INCLUSION_TYPE.upper() not in [y.upper() for y in TableList]:
                self.errorPrinting()
                print self.x

p = MyPrint()
p.myPrint()

函数__init__(self)errorPrinting(self)myPrint(self)都称为“方法”,它们是为类中的任何对象定义的操作。为类之一的实例对象调用这些函数会自动将self参数放在任何包含对该函数所要求的特定实例的引用的参数前面。 self.x指的是由该实例对象存储的变量,因此函数可以共享该变量。

看起来像是对类名称的函数调用:

p = MyPrint()

实际上创建了MyPrint类的新实例对象,调用MyPrint.__init__(<instance>),其中<instance>是新对象,然后将实例分配给p。然后,拨打

p.myprint()

致电MyPrint.myprint(p)

这有一些好处,因为你使用这种方式的变量只有在需要对象时才会持续,你可以有多个计数器用于执行相同操作的不同任务,并且范围都得到了处理,加上你没有弄乱全局命名空间,也不必在你的函数之间传递价值。

答案 3 :(得分:-1)

最简单的解决方案,虽然可能不是最好的风格:

def errorPrinting():
    global x
    x += 1

然后将x = errorPrinting(x)转换为errorPrinting()

&#34;全球x&#34;使函数使用全局定义的x而不是在函数范围内创建一个。

其他例子很好。研究所有这些。