public interface IInterface
{
    void show();
}

 public class MyClass : IInterface
{

    #region IInterface Members

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

    #endregion
}

我如何实现Python等效的这个c#代码?

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!'

这是个好主意吗?请在回答中举例。


当前回答

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这样的动态语言中,接口并不是那么必要。在Java(或具有抽象基类的c++)中,接口是确保传递正确参数,能够执行一组任务的手段。

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

在Python中,没有编译时这样的东西,方法查找是在运行时执行的。此外,可以使用__getattr__()或__getattribute__()魔术方法覆盖查找。换句话说,你可以传递,作为观察者,任何对象,可以返回可调用的访问notify属性。

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

类似这样的东西(可能不起作用,因为我周围没有Python):

class IInterface:
    def show(self): raise NotImplementedError

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

正如其他人在这里提到的:

接口在Python中不是必需的。这是因为Python有适当的多重继承,还有鸭子类型,这意味着在Java中必须有接口的地方,在Python中不必有它们。

也就是说,接口仍然有多种用途。其中一些由Python 2.6中引入的Python抽象基类覆盖。如果你想让基类不能被实例化,但是提供了一个特定的接口或者实现的一部分,它们是很有用的。

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

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 3.8以结构子类型(静态鸭子类型)(PEP 544)的形式为主题提供了什么。

参见简短说明https://docs.python.org/3/library/typing.html#typing.Protocol

下面这个简单的例子是这样的:

from typing import Protocol

class MyShowProto(Protocol):
    def show(self):
        ...


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


class MyOtherClass:
    pass


def foo(o: MyShowProto):
    return o.show()

foo(MyClass())  # ok
foo(MyOtherClass())  # fails

foo(MyOtherClass())将失败的静态类型检查:

$ mypy proto-experiment.py 
proto-experiment.py:21: error: Argument 1 to "foo" has incompatible type "MyOtherClass"; expected "MyShowProto"
Found 1 error in 1 file (checked 1 source file)

此外,你可以显式地指定基类,例如:

class MyOtherClass(MyShowProto):

但请注意,这使得基类的方法实际上在子类上可用,因此静态检查器将不会报告MyOtherClass上缺少方法定义。 因此,在这种情况下,为了获得有用的类型检查,我们希望显式实现的所有方法都应该使用@abstractmethod来装饰:

from typing import Protocol
from abc import abstractmethod

class MyShowProto(Protocol):
    @abstractmethod
    def show(self): raise NotImplementedError


class MyOtherClass(MyShowProto):
    pass


MyOtherClass()  # error in type checker