实例化python2类并在另一个modu中使用的正确方法是什么

2024-10-03 06:23:05 发布

您现在位置:Python中文网/ 问答频道 /正文

这是计数器的类定义(文件名:计数器.py)在复杂的应用中

class Counter:
    def __init__(self):
        self.count = 0
    def incr(self):
        self.count += 1
    def decr(self):
        self.count -= 1

事实证明,这个类只会被实例化两次。这两个实例将由多个模块使用。你知道吗

  1. 读取文件时,计数器1将递增
  2. 当进行HTTP调用时,计数器2将递增

创建Counter类的两个实例的正确方法是什么,以便两个实例的状态可以在整个应用程序中共享?

下面是我提出的解决方案

class Counter:
    def __init__(self):
        self.count = 0
    def incr(self):
        self.count += 1
    def decr(self):
        self.count -= 1

fileCounter = Counter()
httpCounter = Counter()

从另一个模块开始,我会做以下工作

from counter import fileCounter, httpCounter

def readMoxyConfig():
    # Do read the file here
    fileCounter.incr()

def callMoxyAPI():
    # Make the HTTP rest call here
    httpCounter.incr()

这种方法有漏洞吗?如果是的话,达到同样结果的正确方法是什么?

注意:我不想明确地知道全局变量是如何在this question中共享的。我想知道的是从同一个类实例化多个对象并从应用程序中的任何位置访问实例的正确方法。你知道吗


Tags: 模块实例方法selfhttpinitdefcount
3条回答

唯一的漏洞是你会是mutating global state,这通常是不赞成的原因有很多。您可以在main函数中实例化计数器,并将它们传递给需要它们的对象/方法以避免此问题。或者您可能认为全局可变状态适合您的用例,但这至少是您应该考虑的问题。你知道吗

阅读链接文章,了解与全局可变状态相关的问题以及如何避免它。你知道吗

这个全局可变状态是怎样的?

fileCounterhttpCounter这样的模块级变量是全局变量,因为代码的任何部分都可以通过导入模块来访问它们(请注意,这与Python中的global关键字不同)。它们在.count中保持状态,可以通过调用incr().decr()或仅仅赋值来改变状态。你知道吗

通过使实例成为函数的本地实例,代码的其他部分将无法再访问它们,除非显式地传递它们。你知道吗

正确的方法

你的解决方案是“正确的”,因为它会起作用。但它会导致一些你必须意识到的问题。这就是我的答案。你知道吗

实际上,“从应用程序的任何地方访问实例”这件事都是有问题的。随着对象变得越来越复杂,从应用程序的更多部分以更多的方式访问,它会使复杂性增加。你知道吗

我会做的有点不同。这样您就可以在需要时向两个不同的计数器类添加代码。在counter.py中:

class Counter():

    def incr(self, increment = 1):
        self.count += increment

    def decr(self, decrement = 1):
        self.count -= decrement

class httpCounter(Counter):

    def __init__(self, start = 0):
        self.count = start

class fileCounter(Counter):

    def __init__(self, start = 0):
        self.count = start

这样,如果您需要进入其中一个类,可以将其添加到httpCounterfileCounter。或者如果这两个类都有额外的代码,它可以进入Counter类。你知道吗

此外,如果愿意,还可以更改increment/decrement/start值。你知道吗

我认为您可以使用Multiton模式(这里使用Multiton decorator)来避免全局可变州。在这个例子中,类“MyClass”本身的行为就像它的Multiton一样

Multiton

def multiton(cls): instances = {} def getinstance(name): if name not in instances: instances[name] = cls() return instances[name] return getinstance @multiton class MyClass: pass a = MyClass("MyClass0") b = MyClass("MyClass0") c = MyClass("MyClass1") print a is b # True print a is c # False

相关问题 更多 >