在类中调用嵌套函数

时间:2019-04-25 07:31:33

标签: python python-3.x

我正在测试一个小的功能,其中manage()中的barbar函数调用call_central,后者具有函数call2和call3。 我想要call_central上的对象,以便可以在需要时调用call2call3

一些背景:我打算这样做。在我的程序中,call2正在实例化另一个类,而call3使用此信息来执行各种其他操作。

编辑:更多详细信息: 创建嵌套函数的基础如下。假设您正在尝试做一些调度工作并测试各种调度程序。 barbar函数将从“所有”要实现的调度算法中获取所有参数。每种调度算法本身都有类。在此MWE中,它是CallThisClass。 “ call_central”要做的是在call2中实例化此特定的调度算法,并使用它在call3中实际调度

一些问题:

  1. 为什么要求我以“自我”作为论点。
  2. 为什么s(self).call2()返回None
  3. 有没有办法避免为此使用嵌套函数?

代码:

#!/usr/bin/env python3

class CallThisClass:
    def __init__(self):
        pass
    def do_something_here(self):
        while True:
            print ("doing something")

class CallThisClass1:
    def __init__(self):
        pass
    def do_something_here(self):
        while True:
            print ("doing something")


class barbar:
    def __init__(self, which_function=None):
        print ("do nothing")
        self.which_function = which_function
        self.manage()

    def manage(self):
        FUNCTIONS = globals()['barbar']
        s  = getattr(FUNCTIONS, self.which_function)
        print (s(self))#.call2())

    def call_central(self):
        print ("in call central")
        def call2():
            self.invoke_callthisclass = CallThisClass()
            print ("do nothing from call2")
        def call3():
            self.invoke_callthisclass.do_something_here()
            print ("do nothing from call3")
            return 0

    def call_central2(self):
        print ("in call central")
        def call4():
            self.invoke_callthisclass1 = CallThisClass1()
            print ("do nothing from call4")
        def call5():
            self.invoke_callthisclass1.do_something_here()
            print ("do nothing from call5")
            return 0


d = barbar(which_function="call_central")

1 个答案:

答案 0 :(得分:2)

您在这里做的事情很奇怪,但是我会尽力给出一些明智的答案。

为什么要求我将“自我”作为论点。

您的代码如下:

def manage(self):
    FUNCTIONS = globals()['barbar']
    s  = getattr(FUNCTIONS, "call_central")
    print (s(self))#.call2())

您可以等效地编写globals,而不是通过s = barbar.call_central字典。 barbar.call_central unbound 方法。这意味着它是一个实例级方法,没有任何要调用的实例。

为了快速了解Python中对象的工作方式,让我们讨论一个简单得多的类:

class Foo(object):
  def bar(self):
    pass

f = Foo()
print(Foo.bar) # => "<unbound method Foo.bar>"
print(f.bar) # => "bound method Foo.bar of <__main__.Foo object at 0x...>>"

因此,f是类Foo的实例。 bar是一个实例方法-它是Foo实例可以调用的方法。 Foo.bar无实例绑定;要调用它,它需要一个Foo的实例。 f.bar是方法Foo.bar,绑定到实例f。所有这些绑定意味着,无论何时调用该方法,绑定实例都会作为第一个参数传入。这意味着f.bar()Foo.bar(f)基本上做同样的事情。

那么,为什么需要将self作为参数传递给barbar.call_central?因为barbar.call_central是未绑定的实例方法,并且需要调用实例。 self.call_central是您的绑定方法,您可能想调用它。 getattr(self, self.which_function)将为您提供绑定方法。

为什么s(self).call2()不返回None

好吧,这是call2的定义:

def call2():
    self.invoke_callthisclass = CallThisClass()
    print ("do nothing from call2")

没有return,执行只是结束。当执行结束于函数末尾时,它将返回None

您写了这样的东西:

def call2():
    self.invoke_callthisclass = CallThisClass()
    print ("do nothing from call2")
def call3():
    self.invoke_callthisclass.do_something_here()
    print ("do nothing from call3")
    return 0

因为没有缩进,所以您离开了call2的范围,因此以下各行都与该函数没有特别的关系。值得指出的是,call3也永远不会return 0,因为您的do_something_here方法将永远不会返回。

有没有办法避免为此使用嵌套函数?

据我了解您的问题,看来这是您想做的事情:

class BaseScheduler(object):
    def do_the_thing(self):
        raise NotImplementedError("bla bla bla please define a method in {}", type(self))

class Scheduler1(BaseScheduler):
    pass

class Scheduler2(BaseScheduler):
    pass

class BarBarOrWhatever(object):
    def __init__(self, scheduler_cls):
        avaialble_schedulers = BaseScheduler.__subclasses__()
        # Iterate over available_schedulers and do whatever setup you wanted here
        self.__scheduler = scheduler_cls()
        self.__scheduler.do_the_thing()

BarBarOrWhatever(Scheduler1)

您说过,您想让__init__方法对所有可用的调度程序执行某些操作,因此__sublcasses__位正在执行此操作。参见:
How to find all the subclasses of a class given its name?。希望其他一切都相当简单。