如何在python中实现接口?

时间:2022-09-01 09:32:42
public interface IInterface
{
    void show();
}

 public class MyClass : IInterface
{

    #region IInterface Members

    public void show()
    {
        Console.WriteLine("Hello World!");
    }

    #endregion
}

How do I implement Python equivalent of this C# code ?

如何实现与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!'

Is this a good idea?? Please give examples in your answers.

这是个好主意吗?请在你的答案中举例。

5 个解决方案

#1


67  

As mentioned by other here:

正如这里提到的:

Interfaces are not necessary in Python. This is because Python has proper multiple inheritance, and also ducktyping, which means that the places where you must have interfaces in Java, you don't have to have them in Python.

在Python中,接口不是必需的。这是因为Python有正确的多重继承,也有ducktyping,这意味着在Java中必须有接口的地方,您不必在Python中使用它们。

That said, there are still several uses for interfaces. Some of them are covered by Pythons Abstract Base Classes, introduced in Python 2.6. They are useful, if you want to make base classes that cannot be instantiated, but provide a specific interface or part of an implementation.

也就是说,接口仍然有几个用途。其中一些被Python的抽象基类所覆盖,这些类是在Python 2.6中引入的。如果您希望创建不能实例化的基类,但是提供特定的接口或实现的一部分,那么它们是有用的。

Another usage is if you somehow want to specify that an object implements a specific interface, and you can use ABC's for that too by subclassing from them. Another way is zope.interface, a module that is a part of the Zope Component Architecture, a really awesomely cool component framework. Here you don't subclass from the interfaces, but instead mark classes (or even instances) as implementing an interface. This can also be used to look up components from a component registry. Supercool!

另一种用法是,如果您想指定一个对象实现了一个特定的接口,并且您可以使用ABC来实现这个接口,方法是对它们进行子类化。另一种方法是Zope .interface,它是Zope组件体系结构的一部分,一个非常酷的组件框架。在这里,您不必从接口派生子类,而是将类(甚至实例)标记为实现接口。这也可以用于从组件注册中心查找组件。过冷!

#2


25  

Using the abc module for abstract base classes seems to do the trick.

对抽象基类使用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()

#3


19  

There are third-party implementations of interfaces for Python (most popular is Zope's, also used in Twisted), but more commonly Python coders prefer to use the richer concept known as an "Abstract Base Class" (ABC), which combines an interface with the possibility of having some implementation aspects there too. ABCs are particularly well supported in Python 2.6 and later, see the PEP, but even in earlier versions of Python they're normally seen as "the way to go" -- just define a class some of whose methods raise NotImplementedError so that subclasses will be on notice that they'd better override those methods!-)

Python的接口有第三方实现(最流行的是Zope,也在Twisted中使用),但更常见的是Python程序员更喜欢使用更丰富的概念“抽象基类”(ABC),它结合了接口和实现方面的可能性。abc特别支持Python 2.6和以后,看到PEP,但即使在早期版本的Python他们通常被视为“路要走”——只是定义一个类的方法提高NotImplementedError这样子类会注意到他们最好重写这些方法!)

#4


12  

Something like this (might not work as I don't have Python around):

类似这样的东西(可能不能工作,因为我身边没有Python):

class IInterface:
    def show(self): raise NotImplementedError

class MyClass(IInterface):
    def show(self): print "Hello World!"

#5


6  

My understanding is that interfaces are not that necessary in dynamic languages like Python. In Java (or C++ with its abstract base class) interfaces are means for ensuring that e.g. you're passing the right parameter, able to perform set of tasks.

我的理解是,接口在动态语言(如Python)中并不是那么必要。在Java(或c++及其抽象基类)中,接口是确保传递正确参数、能够执行一组任务的手段。

E.g. if you have observer and observable, observable is interested in subscribing objects that supports IObserver interface, which in turn has notify action. This is checked at compile time.

例如,如果你有观察者和可观察的,可观察的感兴趣的是订阅支持IObserver接口的对象,而IObserver接口又有通知动作。在编译时检查。

In Python, there is no such thing as compile time and method lookups are performed at runtime. Moreover, one can override lookup with __getattr__() or __getattribute__() magic methods. In other words, you can pass, as observer, any object that can return callable on accessing notify attribute.

在Python中,不存在编译时和方法查找在运行时执行的事情。此外,还可以使用__getattr__()或__getattribute__()魔法方法重写查找。换句话说,您可以作为观察者传递任何可以返回callable的对象来访问notify属性。

This leads me to the conclusion, that interfaces in Python do exist - it's just their enforcement is postponed to the moment in which they are actually used

这使我得出结论,Python中的接口确实存在——只是它们的实施被推迟到实际使用它们的时刻

#1


67  

As mentioned by other here:

正如这里提到的:

Interfaces are not necessary in Python. This is because Python has proper multiple inheritance, and also ducktyping, which means that the places where you must have interfaces in Java, you don't have to have them in Python.

在Python中,接口不是必需的。这是因为Python有正确的多重继承,也有ducktyping,这意味着在Java中必须有接口的地方,您不必在Python中使用它们。

That said, there are still several uses for interfaces. Some of them are covered by Pythons Abstract Base Classes, introduced in Python 2.6. They are useful, if you want to make base classes that cannot be instantiated, but provide a specific interface or part of an implementation.

也就是说,接口仍然有几个用途。其中一些被Python的抽象基类所覆盖,这些类是在Python 2.6中引入的。如果您希望创建不能实例化的基类,但是提供特定的接口或实现的一部分,那么它们是有用的。

Another usage is if you somehow want to specify that an object implements a specific interface, and you can use ABC's for that too by subclassing from them. Another way is zope.interface, a module that is a part of the Zope Component Architecture, a really awesomely cool component framework. Here you don't subclass from the interfaces, but instead mark classes (or even instances) as implementing an interface. This can also be used to look up components from a component registry. Supercool!

另一种用法是,如果您想指定一个对象实现了一个特定的接口,并且您可以使用ABC来实现这个接口,方法是对它们进行子类化。另一种方法是Zope .interface,它是Zope组件体系结构的一部分,一个非常酷的组件框架。在这里,您不必从接口派生子类,而是将类(甚至实例)标记为实现接口。这也可以用于从组件注册中心查找组件。过冷!

#2


25  

Using the abc module for abstract base classes seems to do the trick.

对抽象基类使用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()

#3


19  

There are third-party implementations of interfaces for Python (most popular is Zope's, also used in Twisted), but more commonly Python coders prefer to use the richer concept known as an "Abstract Base Class" (ABC), which combines an interface with the possibility of having some implementation aspects there too. ABCs are particularly well supported in Python 2.6 and later, see the PEP, but even in earlier versions of Python they're normally seen as "the way to go" -- just define a class some of whose methods raise NotImplementedError so that subclasses will be on notice that they'd better override those methods!-)

Python的接口有第三方实现(最流行的是Zope,也在Twisted中使用),但更常见的是Python程序员更喜欢使用更丰富的概念“抽象基类”(ABC),它结合了接口和实现方面的可能性。abc特别支持Python 2.6和以后,看到PEP,但即使在早期版本的Python他们通常被视为“路要走”——只是定义一个类的方法提高NotImplementedError这样子类会注意到他们最好重写这些方法!)

#4


12  

Something like this (might not work as I don't have Python around):

类似这样的东西(可能不能工作,因为我身边没有Python):

class IInterface:
    def show(self): raise NotImplementedError

class MyClass(IInterface):
    def show(self): print "Hello World!"

#5


6  

My understanding is that interfaces are not that necessary in dynamic languages like Python. In Java (or C++ with its abstract base class) interfaces are means for ensuring that e.g. you're passing the right parameter, able to perform set of tasks.

我的理解是,接口在动态语言(如Python)中并不是那么必要。在Java(或c++及其抽象基类)中,接口是确保传递正确参数、能够执行一组任务的手段。

E.g. if you have observer and observable, observable is interested in subscribing objects that supports IObserver interface, which in turn has notify action. This is checked at compile time.

例如,如果你有观察者和可观察的,可观察的感兴趣的是订阅支持IObserver接口的对象,而IObserver接口又有通知动作。在编译时检查。

In Python, there is no such thing as compile time and method lookups are performed at runtime. Moreover, one can override lookup with __getattr__() or __getattribute__() magic methods. In other words, you can pass, as observer, any object that can return callable on accessing notify attribute.

在Python中,不存在编译时和方法查找在运行时执行的事情。此外,还可以使用__getattr__()或__getattribute__()魔法方法重写查找。换句话说,您可以作为观察者传递任何可以返回callable的对象来访问notify属性。

This leads me to the conclusion, that interfaces in Python do exist - it's just their enforcement is postponed to the moment in which they are actually used

这使我得出结论,Python中的接口确实存在——只是它们的实施被推迟到实际使用它们的时刻