Python 像类一样初始化函数

Python 像类一样初始化函数,python,function,initialization,generator,Python,Function,Initialization,Generator,很多时候,我需要一个简单的函数,在第一次调用时做一些不同的事情。有很多原因,但通常我需要一个不同的初始化变量,如果第一次运行通过。有时我可以在函数外部或内部处理问题,但有时事情会变得一团糟,如果可以避免的话,我不喜欢使用“全局” 我的解决方案来自发电机。我发现我可以“初始化”一个函数,或者在调用时“初始化”一个函数,方法是在程序中使用next()调用,并在函数中的循环上方使用一个reversesed“yield”。工作起来很有魅力 现在我的问题是:有没有更好的方法让我错过 一个WoNUX——有效

很多时候,我需要一个简单的函数,在第一次调用时做一些不同的事情。有很多原因,但通常我需要一个不同的初始化变量,如果第一次运行通过。有时我可以在函数外部或内部处理问题,但有时事情会变得一团糟,如果可以避免的话,我不喜欢使用“全局”

我的解决方案来自发电机。我发现我可以“初始化”一个函数,或者在调用时“初始化”一个函数,方法是在程序中使用next()调用,并在函数中的循环上方使用一个reversesed“yield”。工作起来很有魅力

现在我的问题是:有没有更好的方法让我错过

一个WoNUX——有效但不有用的示例:

o_PrintList = g_PrintThis() ## Creates func object
o_PrintList.next() ## 'Primes' the func
o_PrintList.send(9) ## Sends argument to the func
o_PrintList.send(10) ## Another argument to the func

def g_PrintThis():
    v_PrintList = [] ## Inits the variable. If stnd func call this would happen everytime
    print("Initialized")
    v_Num = yield ## Waits for first send argument
    while True: ## Infinite loop. Could be a for loop, etc.
        v_PrintList.append(v_Num) ## Reason v_PrintList needs 'primed'
        if not v_PrintList:
            print("PrintList is empty:")
        else:
            print("Printlist: %s") %(v_PrintList)
        v_Num = yield ## Waits for next send argument, if ever one comes

谢谢。

一个选择是只使用实际的类。您可以实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来定义调用时

class PrintThis(object):

    def __init__(self, print_list=None):
        if print_list is None:
            print_list = []
        self.print_list = print_list

    def __call__(self):
        if self.print_list:
            print("Print list: {0}".format(self.print_list))
        else:
            print("Print list empty.")

    def send(self, item):
        self.print_list.append(item)
使用中:

>>> p = PrintThis()
>>> p()
Print list empty.
>>> p.send(9)
>>> p.send(10)
>>> p()
Print list: [9, 10]

一种选择是只使用实际的类。您可以实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来定义调用时的适当行为:

class PrintThis(object):

    def __init__(self, print_list=None):
        if print_list is None:
            print_list = []
        self.print_list = print_list

    def __call__(self):
        if self.print_list:
            print("Print list: {0}".format(self.print_list))
        else:
            print("Print list empty.")

    def send(self, item):
        self.print_list.append(item)
使用中:

>>> p = PrintThis()
>>> p()
Print list empty.
>>> p.send(9)
>>> p.send(10)
>>> p()
Print list: [9, 10]

在Python中,函数可以有属性,因此测试给定属性是否存在将允许您确定是否需要初始化:

def f(args):
    if not hasattr(f, "guard"):
        print "Initializing"
        f.guard = None
    print "Called with", args

f("one")
f("two")
印刷品

Initializing
Called with one
Called with two

这避免了使用全局变量,而全局变量通常表示麻烦的潜在问题(如果其他代码使用相同的全局变量,只问一个相关问题会怎么样)。

Python中的函数可以有属性,因此测试给定属性是否存在将允许您确定是否需要初始化:

def f(args):
    if not hasattr(f, "guard"):
        print "Initializing"
        f.guard = None
    print "Called with", args

f("one")
f("two")
印刷品

Initializing
Called with one
Called with two
这避免了使用全局变量,而全局变量通常表示麻烦的潜在问题(如果其他代码使用相同的全局变量,只问一个相关问题会怎么样)。

函数也是类(确切地说是第一类)。调用函数时,实际上调用了函数的类“
\uuuuu call\uuuu
方法,该方法也是一个类

正如jonrsharpe所说,创建一个类并实现
\uuuuu init\uuuuuuu
\uuuu调用
方法。

函数也是类(确切地说是第一类)。调用函数时,实际上调用了函数的类“
\uuuuu call\uuuu
方法,该方法也是一个类


就像jonrsharpe所说的,创建一个类并实现
\uuuu init\uuuuuuu
\uuu调用
方法。

看看是否显式调用
next
来初始化它,您也可以使用一个单独的
setup\u printing
函数,并在第一次设置时调用它。查看是否显式调用
next
来初始化它,您最好使用一个单独的
setup\u printing
函数,并在首次设置时调用该函数。函数体中函数的设置属性充其量是脆弱的。如果需要状态,请使用类(或最终使用闭包…。@holdenweb谢谢。这是我经常得出的解决方案的一种形式。然而,它有时会变得复杂和/或在随后的电话中中断。请解释一下?对于这个解决方案的脆弱性,我不同意Bruno的观点,尤其是我认为必须声明一个类(我知道它只有一个实例)是令人反感的。函数体中函数的设置属性充其量是脆弱的。如果需要状态,请使用类(或最终使用闭包…。@holdenweb谢谢。这是我经常得出的解决方案的一种形式。然而,它有时会变得复杂和/或在随后的电话中中断。请解释一下?我不同意Bruno关于这个解决方案的脆弱性的观点,特别是我发现必须声明一个我知道只有一个实例的类是令人反感的。你说的很多是正确的,但是如果函数是类,我们就可以从它们继承。它们是函数类型的实例。您不能继承
类型。FunctionType
。是的,动态构建functin(因为它是一个模块)非常困难。它们可能是一级对象,但它们不是真正的一级类型。你说的没错,但如果函数是类,我们就可以从它们继承。它们是函数类型的实例。您不能继承
类型。FunctionType
。是的,动态构建functin(因为它是一个模块)非常困难。它们可能是一流的对象,但它们并不是真正的一流对象types@jonsharpe谢谢当然,一个类是可以工作的,但是对于一个简单的函数来说,它会变成很多代码并且更加复杂。我还倾向于将函数分类为“任务”,将类分类为“实体”。我将东西发送给要完成并返回的任务,并发送实体去做并保存东西。对于一个简单的任务,我真的想创建一个实体吗?值得思考。@Raw_Input您的任务和实体的区别在Python中并不普遍适用,在您的示例中也不特别适用;在这种情况下,您希望您的任务也包含内容@谢谢你。当然,一个类是可以工作的,但是对于一个简单的函数来说,它会变成很多代码并且更加复杂。我还倾向于将函数分类为“任务”,将类分类为“实体”。我将东西发送给要完成并返回的任务,并发送实体去做并保存东西。对于一个简单的任务,我真的想创建一个实体吗?值得思考。@Raw_Input您的任务和实体的区别在Python中并不普遍适用,在您的示例中也不特别适用;在这种情况下,您希望您的任务也包含内容!