在类之间传输数据并使用def,而没有实例可能是单例模式

2024-04-26 09:36:36 发布

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

Class2是我的主应用程序,它显示favList中的按钮列表。 在displayLibrary中,我用Class1实例创建按钮。 当用户单击一个按钮(simulateButtonClick)时,我必须从Class1运行duplicateNetwork函数 在那里,我会做所有必要的东西复制对象在Maya中,我想添加这个材料使用Class2.addSlot函数(因为我有很多检查那里,不想不必要的代码)

因此,我们的任务是建立这些联系: 1从Class2.displayLibrary->;使用Class1实例创建按钮 2使用Class2.simulateButtonClick时->;转到Class1.duplicateNetwork->;转到Class2.addSlot 第二个是最难的,因为当我从button调用duplicateNetwork时,我调用的是我之前创建的实例,它很好。 但是当我想回到Class2.addSlot时,我不能创建实例。我只能用我唯一用的一个。 这就是为什么我试着使用Singleton。你知道吗

我对引起错误的那两行进行了注释。你知道吗

favList = []
buttons = {}
favList.append("shader1")
favList.append("shader2")
favList.append("shader3")
favList.append("shader4")

class Singleton(object):
    _instances = {}
    def __new__(class_, *args, **kwargs):
        if class_ not in class_._instances:
            class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
        else:
            # class_._instances[class_].__init__(class_, *args, **kwargs)
            class_._instances[class_].__init__(*args, **kwargs)
        return class_._instances[class_]

class Class1(Singleton):
    def __init__(self, name):
        print ("Just test if name is working: {0}").format(name)

    @staticmethod
    def duplicateNetwork(self):
        newMaterial = "shader8000"
        Class2.addSlot(newMaterial)

class Class2(Singleton):
    def __init__(self):
        print "Do something in Class2"
        self.displayLibrary()
        self.simulateButtonClick()

    def addSlot(self, shaderName=None):
        favList.append(shaderName)
        self.displayLibrary()

    def displayLibrary(self):
        for i,obj in enumerate(favList):
            # create button with Class1 Instance
            buttons[i] = Class1(obj)
            print("Shader library contains: {0}").format(obj)

    def simulateButtonClick(self):
        material = "Shader6000"
        # Simulate click for button "Shader1"
        buttons[0].duplicateNetwork(self)


run = Class2()

现在我犯了错误: 按钮[i]=Class1(obj)

Traceback (most recent call last):
  File "G:\kTools\singlethon.py", line 46, in <module>
    run = Class2()
  File "G:\kTools\singlethon.py", line 27, in __init__
    self.displayLibrary()
  File "G:\kTools\singlethon.py", line 38, in displayLibrary
    buttons[i] = Class1(obj)
  File "G:\kTools\singlethon.py", line 13, in __new__
    class_._instances[class_].__init__(class_, *args, **kwargs)
TypeError: __init__() takes exactly 2 arguments (3 given)

那是因为在辛格尔顿我得到了其他的课程。我也评论了那句话,但你能告诉我为什么吗?我不知道为什么要有*args**kwargs,我基本上知道它们是什么,但不知道为什么我在Singleton中需要它们。你知道吗

第二个错误是:

Traceback (most recent call last):
  File "G:\kTools\singlethon.py", line 49, in <module>
    run = Class2()
  File "G:\kTools\singlethon.py", line 31, in __init__
    self.simulateButtonClick()
  File "G:\kTools\singlethon.py", line 46, in simulateButtonClick
    buttons[0].duplicateNetwork(self)
  File "G:\kTools\singlethon.py", line 25, in duplicateNetwork
    Class2.addSlot(newMaterial)
TypeError: unbound method addSlot() must be called with Class2 instance as first argument (got str instance instead)

对于这一次,我从一开始就遇到了问题。不知道怎么解决。你知道吗


Tags: inpyselfinitlineclassfileclass1
2条回答

好吧,我想我能修好它。 你刚才的self作为一个参数丢失了。你知道吗

RightClickMenuButton.duplicateNetwork(self)

当我运行它时,我在第27行遇到了另一个错误,所以我通过再次添加self来修复这个错误。你知道吗

favoriteMaterial_UI.addSlot(self, shader)

所以最后的代码是。你知道吗

favList = []
favList.append("shader1")
favList.append("shader2")
class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        else:
            cls._instances[cls].__init__(*args, **kwargs)
            # class_._instances[class_].__init__(class_, *args, **kwargs)
        return cls._instances[cls]

class RightClickMenuButton(object):
    __metaclass__ = Singleton
    def __init__(self):
        print("Sygnal z Init RightClickMenu")
        self.addMenuActions()

    def addMenuActions(self):
        print("Sygnal z  addMenuActions")
        self.duplicateNetwork()

    def duplicateNetwork(self):
        shader = "shader3"
        print("Sygnal z  duplikateNetwork")
        favoriteMaterial_UI.addSlot(self, shader)

class favoriteMaterial_UI(object):
    __metaclass__ = Singleton
    def __init__(self):
        print("Sygnal z  init favoriteMaterial_UI")
        self.displayLibrary()
        self.wymuszonyKlikPrzycisku()

    def wymuszonyKlikPrzycisku(self):
        print("click")
        RightClickMenuButton.duplicateNetwork(self)

    def addSlot(self, obj):
        favList.append(obj)
        self.refreshSlot()

    def displayLibrary(self):
        print("Wyswietlam liste:")
        for obj in favList:
            print(obj)

    def refreshSlot(self):
        print("Sygnal z  refreshSlot")
        self.displayLibrary()


c = favoriteMaterial_UI()

如果这不是你在哪里找的我希望其他人能帮助你!:)

在看到新的编辑之后,我认为您只需要在每个Class1中引用Class2,这样就可以了(您可能不需要Singleton):

from weakref import proxy

favList = []
buttons = {}
favList.append("shader1")
favList.append("shader2")
favList.append("shader3")
favList.append("shader4")

class Class1:
    def __init__(self, name, parent):
        self.parent = proxy(parent)
        print ("Just test if name is working: {0}").format(name)

    def duplicateNetwork(self):
        newMaterial = "shader8000"
        self.parent.addSlot(newMaterial)

class Class2:
    def __init__(self):
        print "Do something in Class2"
        self.displayLibrary()
        self.simulateButtonClick()

    def addSlot(self, shaderName=None):
        favList.append(shaderName)
        self.displayLibrary()

    def displayLibrary(self):
        for i,obj in enumerate(favList):
            # create button with Class1 Instance
            buttons[i] = Class1(obj, parent=self)
            print("Shader library contains: {0}").format(obj)

    def simulateButtonClick(self):
        material = "Shader6000"
        # Simulate click for button "Shader1"
        buttons[0].duplicateNetwork()


run = Class2()

相关问题 更多 >