Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何处理无法正确初始化的类上的方法调用?_Python_Oop_Coding Style_Module_Refactoring - Fatal编程技术网

Python:如何处理无法正确初始化的类上的方法调用?

Python:如何处理无法正确初始化的类上的方法调用?,python,oop,coding-style,module,refactoring,Python,Oop,Coding Style,Module,Refactoring,如果对象依赖于Python中未包含的模块(如win32api、gstreamer、gui工具包等),并且该模块中的类/函数/方法可能会失败,那么该对象应该怎么做 下面是一个例子: import guimodule # Just an example; could be anything class RandomWindow(object): def __init__(self): try: self.dialog = guimodule.Di

如果对象依赖于Python中未包含的模块(如win32api、gstreamer、gui工具包等),并且该模块中的类/函数/方法可能会失败,那么该对象应该怎么做

下面是一个例子:

import guimodule  # Just an example; could be anything

class RandomWindow(object):

    def __init__(self):
        try:
            self.dialog = guimodule.Dialog()  # I might fail
        except: guimodule.DialogError:
            self.dialog = None  # This can't be right

    def update(self):
        self.dialog.prepare()
        self.dialog.paint()
        self.dialog.update()

    # ~30 more methods
这个类只是更大程序中的一小部分(不必要但有用)

假设我们有一个名为
guimodule
的虚构模块,其中有一个名为
Dialog
的类,该类可能无法实例化。如果我们的
RandomWindow
类有30个方法来操作这个窗口,检查
self.dialog是否为None
将是一件痛苦的事情,并且在经常使用的方法(如上面示例中的
update
方法)中实现时会减慢程序的速度。在
非类型
上调用
.paint()
(当
对话框
加载失败时)将引发错误,并且使用原始的所有方法和属性创建一个虚拟的
对话框
类将是荒谬的


如何修改我的类来处理创建
对话框失败的问题?

您可能会发现有两个子类很有用;一个使用该模块,一个不使用该模块。“工厂”方法可以确定哪个子类是合适的,并返回该子类的实例


通过子类化,您可以让他们共享与模块是否可用无关的代码。

您可能会发现有两个子类很有用;一个使用该模块,一个不使用该模块。“工厂”方法可以确定哪个子类是合适的,并返回该子类的实例


通过子类化,您允许他们共享独立于该模块是否可用的代码。

您不应该创建无效对象,而是应该允许在
\uuuu init\uuuu
中引发的异常传播出去,以便以适当的方式处理错误。或者你可以提出一个不同的例外


另请参见

而不是创建无效对象,您应该允许在
\uuuu init\uuuu
中引发的异常传播出去,以便以适当的方式处理错误。或者你可以提出一个不同的例外

另请参见

我同意“检查self.dialog是否不存在会很痛苦”,但我不同意它会减慢速度,因为如果self.dialog存在,它会更慢。所以暂时忘掉缓慢。因此,一种处理方法是创建一个MockDialog,它对函数调用不做任何操作,例如

class RandomWindow(object):

    def __init__(self):
        try:
            self.dialog = guimodule.Dialog()  # I might fail
        except: guimodule.DialogError:
            self.dialog = DummyDialog() # create a placeholder

class DummyDialog(object):
    # either list all methods or override __getattr__ to create a mock object
我同意“检查self.dialog是否没有将是痛苦的”,但我不同意它会减慢速度,因为如果存在self.dialog,它将更慢。所以暂时忘掉缓慢。因此,一种处理方法是创建一个MockDialog,它对函数调用不做任何操作,例如

class RandomWindow(object):

    def __init__(self):
        try:
            self.dialog = guimodule.Dialog()  # I might fail
        except: guimodule.DialogError:
            self.dialog = DummyDialog() # create a placeholder

class DummyDialog(object):
    # either list all methods or override __getattr__ to create a mock object

制作一个哑<代码>对话框类并不像你认为的那样使用Python <代码>以下虚拟实现将完全满足您的需要:

class DummyDialog:
  def __getattr__(self, name):
    def fct(*args, **kwargs):
      pass
    return fct 

制作一个哑<代码>对话框类并不像你认为的那样使用Python <代码>以下虚拟实现将完全满足您的需要:

class DummyDialog:
  def __getattr__(self, name):
    def fct(*args, **kwargs):
      pass
    return fct 

这样做的问题是,每次修改原始文件时,我都必须修改伪/子类(保持同步会很烦人)。问题是每次修改原始文件时,我都必须修改伪/子类(保持同步会很烦人)。如果有返回方法呢?你是对的,具有返回值的对话框方法不能像这样模拟。要么在
DummyDialog
中分别定义它们并返回任何伪值,要么必须选择Aaron提出的涉及子类化的完全不同的方法。如果有返回方法呢?没错,具有返回值的对话框方法不能像这样被模拟。要么在
DummyDialog
中单独定义它们并返回任何伪值,要么选择Aaron建议的涉及子类化的完全不同的方法。为什么这比让类在内部处理错误更好/更简单?@DK,直接知道对象不能使用比每次使用对象都失败更简单。为什么这比让类在内部处理错误更好/更简单?@DK,直接知道对象不能使用比每次使用对象都失败更简单。