Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.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 2.5的抽象类_Python_Refactoring - Fatal编程技术网

Python 2.5的抽象类

Python 2.5的抽象类,python,refactoring,Python,Refactoring,我目前正在重构一个定义客户机或服务器的类。这个班有很多学生 if client: XXXXXXXXXXXX elif server: YYYYYYYYYYYY 所以我决定用类似的代码创建一个类a,一个类C用于客户端,另一个类S用于服务器,服务器继承了a。(当然,它们没有这些名称^^) 所以类A是一种抽象类。但问题是Python2.5中没有抽象类,它是2.6版本的。所以我想知道是否有办法禁止类a的实例化 一种解决方案是在类a的构造函数中引发NotImplemented错误,但C和

我目前正在重构一个定义客户机或服务器的类。这个班有很多学生

if client:
    XXXXXXXXXXXX
elif server:
    YYYYYYYYYYYY
所以我决定用类似的代码创建一个类a,一个类C用于客户端,另一个类S用于服务器,服务器继承了a。(当然,它们没有这些名称^^)

所以类A是一种抽象类。但问题是Python2.5中没有抽象类,它是2.6版本的。所以我想知道是否有办法禁止类a的实例化

一种解决方案是在类a的构造函数中引发NotImplemented错误,但C和S的代码相同,所以我将其放在“抽象”类a中(坏主意?)

这可能看起来很愚蠢,但我只是偶尔用Python开发,而且我是一个年轻的程序员。 你的建议是什么?

你想要什么就有什么

不适用于2.5。

对于您想要的内容,有一个解决方案


不适用于2.5。

真正的问题是:为什么需要抽象类


如果您创建两个类,并从第一个类创建第二个类,这是清理代码的有效方法。

真正的问题是:为什么需要抽象类


如果您创建两个类,并从第一个类创建第二个类,这是清理代码的有效方法。

您可以在构造函数开头调用方法“foo”。在中,此方法引发异常。在C和S中,您重新定义了“foo”,因此不再有异常。

您可以在构造函数的开头调用方法“foo”。在中,此方法引发异常。在C和S中,您重新定义了“foo”,这样就没有更多的异常了。

我的第一个问题是:为什么您不能简单地避免从类
A
实例化对象?我的意思是这有点像。。。如正确引用的:

在“四人帮”对我们进行学术研究之前,“单身”(没有正式名称)只是一个简单的想法,应该有一行简单的代码,而不是整个宗教

同样的-IMO-也适用于抽象类(实际上,Python中引入的抽象类比您打算使用它们的抽象类要多)

也就是说,您可以在类
A
\uuuu init\uuuu
方法中引发异常。类似于:

>>> class A():
...     def __init__(self):
...             raise BaseException()
... 
>>> a = A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
BaseException
>>> class B(A):
...     def __init__(self):
...             pass
... 
>>> b = B()
>>>
>A类()
…定义初始化(自):
…引发BaseException()
... 
>>>a=a()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第3行,在_init中__
基本例外
>>>B(A)类:
…定义初始化(自):
…通过
... 
>>>b=b()
>>>

当然这只是一个粗略的想法:例如,如果你在
A中有一些有用的东西,你应该检查
\uuu class\uuuu
属性,等等…

我的第一个问题是:为什么你不能简单地避免从class
A
实例化一个对象?我的意思是,这有点像…正确地引用d:

在“四人帮”对我们进行学术研究之前,“单身”(没有正式名称)只是一个简单的想法,应该有一行简单的代码,而不是整个宗教

同样的-IMO-也适用于抽象类(实际上,Python中引入的抽象类比您打算使用它们的抽象类要多)

也就是说,您可以在类
A
\uuuu init\uuuu
方法中引发异常。类似于:

>>> class A():
...     def __init__(self):
...             raise BaseException()
... 
>>> a = A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
BaseException
>>> class B(A):
...     def __init__(self):
...             pass
... 
>>> b = B()
>>>
>A类()
…定义初始化(自):
…引发BaseException()
... 
>>>a=a()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第3行,在_init中__
基本例外
>>>B(A)类:
…定义初始化(自):
…通过
... 
>>>b=b()
>>>

当然,这只是一个粗略的想法:例如,如果你在
A.中有一些有用的东西,你应该检查
\uuu class\uuuu
属性,等等。

这种方法的优点是你不需要对子类做任何事情来使它非抽象

class ABC(object):
    abstract = True
    def __new__(cls, *args, **kwargs):
        if "abstract" in cls.__dict__ and cls.__dict__["abstract"] == True:
            raise RuntimeError(cls.__name__ + " is abstract!")
        return object.__new__(cls)

class Subclass(ABC):
    pass

print Subclass()
print ABC()
输出:

<__main__.Subclass object at 0xb7878a6c>
Traceback (most recent call last):
  File "abc.py", line 14, in <module>
    print ABC()
  File "abc.py", line 6, in __new__
    raise RuntimeError(cls.__name__ + " is abstract!")
RuntimeError: ABC is abstract!

这种方法的优点是不需要对子类做任何事情就可以使其非抽象

class ABC(object):
    abstract = True
    def __new__(cls, *args, **kwargs):
        if "abstract" in cls.__dict__ and cls.__dict__["abstract"] == True:
            raise RuntimeError(cls.__name__ + " is abstract!")
        return object.__new__(cls)

class Subclass(ABC):
    pass

print Subclass()
print ABC()
输出:

<__main__.Subclass object at 0xb7878a6c>
Traceback (most recent call last):
  File "abc.py", line 14, in <module>
    print ABC()
  File "abc.py", line 6, in __new__
    raise RuntimeError(cls.__name__ + " is abstract!")
RuntimeError: ABC is abstract!

在静态类型语言中,您使用抽象基类(ABC),因为您需要一些具有定义大小、接口等的对象来传递。否则,无法编译试图调用该对象上的方法的代码

Python不是一种静态类型的语言,调用代码根本不需要知道它调用的对象的类型。因此,您可以通过记录接口需求并直接在两个不相关的类中实现该接口来“定义”ABC

例如


在这里,您可以使用参数与调用匹配的do_thing方法传入任何对象。

在静态类型语言中,您使用抽象基类(ABC),因为您需要一些具有定义大小、接口等的对象来传递。否则,无法编译尝试调用该对象上的方法的代码

Python不是一种静态类型的语言,调用代码根本不需要知道它调用的对象的类型。因此,您可以通过记录接口需求并直接在两个不相关的类中实现该接口来“定义”ABC

例如


在这里,您可以通过Dou-thing方法传入任何对象,该方法的参数与调用匹配。

在2.6版中新增,正如OP在问题中所说,他使用2.5。是的,我必须继续使用2.5版。问题确实明确提到了Python 2.5,并且在2.6版中引入了
abc
。(尽管升级和使用
abc
对我来说似乎是最好的解决方案。)OP已经知道了。事实上,它提到了ABC是在Python的2.6版本中引入的……在2.6版本中是新的,正如OP在他的问题中所说,他使用了2.5。是的,我必须坚持使用2.5版本。问题确实明确提到了Python 2.5,
ABC
是在2.6中引入的