【问题标题】:Counter instance method with inner class具有内部类的计数器实例方法
【发布时间】:2020-07-21 21:53:51
【问题描述】:

我正在构建一个函数管道,我需要知道为索引每个函数打开了多少类实例, 我还需要将 init 计数器的“开始”参数设置为 0,因为它处理同一管道多次运行而计数不会超过限制。

首先,我构建了一个仅适用于一个管道的方法,因为计数器与其他管道类共享

class Foo3():
    class Counter:
        def __init__(self,func):
            self.counter = 0
            self.func = func
            #Counter.method  =method
        def __call__(self,*args, **kwds):
            self.counter += 1
            return self.func(*args, **kwds)



    #count= Counter()
    string = 'this is '
    start = True

    def __init__(self, name):
        self.name = name
        #self.method = method
        self.ainit(self)
        self.newinst()
        print(self.newinst.counter)
    @Counter
    def newinst():
        pass
    @classmethod
    def ainit(cls,inst):
        print(cls.string +inst.name)

    @classmethod
    def getCount(cls,inst):
        print(self.newinst.counter) 

class pipe1(Foo3):
    pass
class pipe2(Foo3):
    pass 
pipe1('test')
pipe1('test2')
pipe1('test3')
pipe2('test_new')

输出

this is test
1
this is test2
2
this is test3
3
this is test_new
4

现在我试图弄清楚如何在 Counter 类中传递一个 start 方法,以指示管道从哪里开始。 但是我的解决方案不起作用,因为我尝试以错误的方式使用@static 方法

class Foo3():
    class Counter:
        method = 'regular'
        def __init__(self,func,method:str='regular' ):
            self.counter = 0
            self.func = func
            Counter.method  =method
        def __call__(self,method,*args, **kwds):
            if Counter.method == 'Start':
                print('count = 0')
                self.counter = 0
            if Counter.method == 'regular' :  
                print('+1')
                self.counter += 1
            return self.func(*args, **kwds)

    #count= Counter()
    string = 'this is '
    start = True
    @Counter
    @staticmethod
    def newinst(method='regular'):
        pass
    def __init__(self, name, method:str='regular'):
        self.name = name
        self.method = method
        print(self.ainit(self))
        Foo3.newinst(method)
        print(self.newinst.counter)

    @classmethod
    def ainit(cls,inst):
        print(cls.string +inst.name)

    @classmethod
    def getCount(cls,inst):
        print(self.newinst.counter) 

如果我使用计数器类作为解决方案,那是因为我希望每个管道有一个计数

class pipe1(Foo3):
    pass
class pipe2(Foo3):
    pass    


pipe1('test', 'Start')
pipe1('test2')
pipe1('test3')
pipe2('test_new', 'Start')
pipe1.getCount()
pipe2.getCount()

预期输出:

this is test

1
this is test2
2
this is test3
3
this is test_new
1
3
1

但我遇到了问题:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-440-1710b9b56152> in <module>
     54 
     55 if __name__ == "__main__":
---> 56     Foo3('a')

<ipython-input-440-1710b9b56152> in __init__(self, name, method)
     43         self.name = name
     44         self.method = method
---> 45         Foo3.newinst(method)
     46         print(self.newinst.counter)
     47 

<ipython-input-440-1710b9b56152> in __call__(self, method, *args, **kwds)
     29                 print('+1')
     30                 self.counter += 1
---> 31             return self.func(*args, **kwds)
     32 
     33 

TypeError: 'staticmethod' object is not callable

【问题讨论】:

  • "如果我使用嵌套类作为解决方案,那是因为我希望每个管道有一个计数" 第一个与第二个有何关系?您只为每个实例创建了一个 Counter 实例,一个非常单一的类不会替换 Counter.__init__
  • 我无法使用所示代码重现该问题。像这样嵌套Counter 是无效的,因为Counter 是一个类变量,在Foo3.Counter.__init__ 和其他方法的嵌套范围内是不可见的。这意味着代码已经在@Counter 行失败。
  • 请注意,newinst 不应声明为静态方法,因为它作为函数传递给Counter,然后被Counter 实例替换。它从不用作方法。
  • 我无法使用它,但我遇到了关于 self 和 cls 的问题,否则,如果我删除静态方法,它可以工作,但我没有设法使用 'Start' 参数
  • 好吧,你的代码有多个问题,比如ainit被声明为类方法但期待一个实例,getCount使用self但没有收到它,Counter适用于所有管道,也许还有更多。非常不清楚您要做什么,以及如何帮助您。请咨询How to Ask help page,并尝试用我们可以实际回答的明确问题陈述来制定问题。

标签: python python-3.x class static-methods python-decorators


【解决方案1】:

我找到了解决办法

class Foo3():
    class Counter:

        method = 'regular'
        def __init__(self,func, method= 'regular'):
            self.counter = 0
            self.func = func
            #print(method)
            Counter.method  =method
            #print(Counter.method)
        def __call__(self,*args,method ='regular', **kwds):

            if method == 'Start':
                self.counter =0
            elif method =='regular':
                self.counter += 1
            else :
                raise Exception("this method doesn't exist")
            return self.func(*args, **kwds)



    #count= Counter()
    string = 'this is '
    start = True
    @Counter
    def newinst(method='regular'):
        pass
    def __init__(self, name, method= 'regular'):
        self.name = name
        #self.method = method
        self.ainit(self)
        self.newinst(method=method)
        print(self.newinst.counter)

    @classmethod
    def ainit(cls,inst):
        print(cls.string +inst.name)

    @classmethod
    def getCount(cls,inst):
        print(self.newinst.counter) 


输出

class pipe1(Foo3):
    pass
class pipe2(Foo3):
    pass    
pipe1('test', 'Start')
pipe1('test2')
pipe1('test3')
pipe2('test_new','Start')

this is test
0
this is test2
1
this is test3
2
this is test_new
0

我的错误来自我对decorator 和内部Class 的了解不足,在我的示例中,Counter 的__init__ 函数甚至在我构建管道之前就已实例化,然后我没有弄清楚如何通过'我在 init 函数中设置的参数中的 Start'。 现在我的另一个问题 - 正如@MisterMiyagi 提到的那样 - 来自我的getCount()function 不应该工作的事实,我最好避开 Counter 类,但我仍然没有弄清楚每个Counter 实例如何打开pipeline 继承 Foo3,但未在“pipline Class global”参数中指定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多