public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
如何实现与此C#代码等效的Python代码?
class IInterface(object):
def __init__(self):
pass
def show(self):
raise Exception("NotImplementedException")
class MyClass(IInterface):
def __init__(self):
IInterface.__init__(self)
def show(self):
print 'Hello World!'
这是个好主意吗?请在你的答案中举例说明。
发布于 2014-04-17 21:11:36
使用抽象基类的abc模块似乎可以做到这一点。
from abc import ABCMeta, abstractmethod
class IInterface:
__metaclass__ = ABCMeta
@classmethod
def version(self): return "1.0"
@abstractmethod
def show(self): raise NotImplementedError
class MyServer(IInterface):
def show(self):
print 'Hello, World 2!'
class MyBadServer(object):
def show(self):
print 'Damn you, world!'
class MyClient(object):
def __init__(self, server):
if not isinstance(server, IInterface): raise Exception('Bad interface')
if not IInterface.version() == '1.0': raise Exception('Bad revision')
self._server = server
def client_show(self):
self._server.show()
# This call will fail with an exception
try:
x = MyClient(MyBadServer)
except Exception as exc:
print 'Failed as it should!'
# This will pass with glory
MyClient(MyServer()).client_show()
发布于 2018-07-11 04:06:48
在现代Python3中,使用抽象基类实现接口要简单得多,它们用作插件扩展的接口契约。
创建接口/抽象基类:
from abc import ABC, abstractmethod
class AccountingSystem(ABC):
@abstractmethod
def create_purchase_invoice(self, purchase):
pass
@abstractmethod
def create_sale_invoice(self, sale):
log.debug('Creating sale invoice', sale)
创建一个normal子类并覆盖所有抽象方法:
class GizmoAccountingSystem(AccountingSystem):
def create_purchase_invoice(self, purchase):
submit_to_gizmo_purchase_service(purchase)
def create_sale_invoice(self, sale):
super().create_sale_invoice(sale)
submit_to_gizmo_sale_service(sale)
您可以选择在抽象方法中使用通用实现,就像在create_sale_invoice()
中一样,在子类中使用super()
显式调用它,如上所述。
没有实现所有抽象方法的子类的实例化失败:
class IncompleteAccountingSystem(AccountingSystem):
pass
>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
通过将相应的注解与@abstractmethod
相结合,您还可以拥有抽象属性、静态方法和类方法。
抽象基类非常适合实现基于插件的系统。类的所有导入的子类都可以通过__subclasses__()
访问,因此如果您使用importlib.import_module()
从插件目录加载所有类,并且如果它们是基类的子类,则可以通过__subclasses__()
直接访问它们,并且可以确保在实例化期间对所有这些类执行接口约定。
下面是上面AccountingSystem
示例的插件加载实现:
...
from importlib import import_module
class AccountingSystem(ABC):
...
_instance = None
@classmethod
def instance(cls):
if not cls._instance:
module_name = settings.ACCOUNTING_SYSTEM_MODULE_NAME
import_module(module_name)
subclasses = cls.__subclasses__()
if len(subclasses) > 1:
raise InvalidAccountingSystemError('More than one '
f'accounting module: {subclasses}')
if not subclasses or module_name not in str(subclasses[0]):
raise InvalidAccountingSystemError('Accounting module '
f'{module_name} does not exist or does not '
'subclass AccountingSystem')
cls._instance = subclasses[0]()
return cls._instance
然后,您可以通过AccountingSystem
类访问会计系统插件对象:
>>> accountingsystem = AccountingSystem.instance()
(灵感来自this PyMOTW-3 post。)
发布于 2018-10-24 12:08:11
interface支持Python2.7和Python 3.4+。
要使用install接口,您必须
pip install python-interface
示例代码:
from interface import implements, Interface
class MyInterface(Interface):
def method1(self, x):
pass
def method2(self, x, y):
pass
class MyClass(implements(MyInterface)):
def method1(self, x):
return x * 2
def method2(self, x, y):
return x + y
https://stackoverflow.com/questions/2124190
复制相似问题