Movatterモバイル変換


[0]ホーム

URL:


PEP 245

Alex Shindichshindich at itginc.com
Wed Apr 4 18:25:12 EDT 2001


Michel,Thank you for the explanations! Your reply did clear up some of theconcerns I had regarding this PEP.I still have a few objections though:>> 1. What is the point of interfaces without static typing?>To assert a contract is one.  To separate various implementations of the>same interface without them loosing a common usage is another.>No mandatory enforcement is being proposed.This means that interface support in Python will be limited to threeapplications:1. Clear documentation of the interfaces2. Separation of inheritence hierarchy from the implementation hierarchy3. An ability to dtermine if a particular object supports a specificinterface.Am I missing anything out?>> 2. At what point will the compliance with the interface definition be>> done, at compile time, or at run time?>There is no madatory compliance or interface enforcement proposed in 245.>These things are optional, and they should be optional.  Turn on for>unit-testing, debugging, etc, turn off for production and speed.Great!>> If the compliance is checked at run time, then interface checking is as>> good as as simply assuming that the method is implemented. Today, I can>> compile code like "f.doSomething ()" without f actually implementing>> doSomething. At run time I would get an AttributeError thrown into my>> face. In fact, the run time compliance is available already.>>Interfaces, strong or weak, are not going to solve any of these problems>in a magic bullet fasion. There's a million ways around even strong>interfaced languaged, even ones that go so far as to check pre and>post-condition contract boundaries.I was not trying to identify the problems. On the contrary, my point wasthat run-time checking is supported today, i.e. if the method is notpresent, an AttributeError exception will be thrown.BTW. Are you planning on throwning an InterfaceError exception instead ofAttributeError?>One of the major reasons for the PEP is to assert that an object can be>used in a certain way, without caring about how it is implemented.  It's>telling you something about what it can do, without you having to know the>difference between the flat-file implementation and the one that uses a>relational database.>Currently this ability in Python is weak, and is based on looking at>classes.  But classes are not meant to be explicit interfaces, they are>ways of sharing implementaiton.I see your point. But I think that proposed interface behavior is missing avery important attribute -- an explicit facility for acquiring interfacereferences. Per you proposal, the reference to the object isindistinguishable from the reference to the interface. In Java the referenceto the interface is obtained using a type cast, i.e.IProgrammer prg = (IProgrammer) obj;In COM, the same is accomplished through the use of QueryInterface, i.e.IProgrammer * pIProgrammer = NULL;HRESULT hr = pIObj->QueryInterface (IID_IProgrammer,reinterpret_cast<void**> (&pIProgrammer));if (SUCCEEDED (hr))...orCComQIPtr<IProgrammer, &IID_IProgrammer> tIProgrammer(pIObj);if (!tIProgrammer)...There is no such thing proposed in PEP 245.If the interfaces are added to Python, I would like to have a way ofdistinguishing between references to the object and references to theinterface. In fact, I would like that to be more similar with COM ruleswhere class implmenetor is responsible for the implementation ofQueryInterface (although default behaviour should be provided). This permitsplaying all sorts of identity tricks, such as component aggregation, andtear-offs. How about adding __getinterfacereference__ that as name impliesreturns the interface reference? I guess a built-ingetinterface (object, interface) -> interface referencewould have to be added as well.>No, Java interfaces are just compile time enforcement.  The syntax is>vaguely similar.But the concept is similar. Java interfaces assert a contract, and allowdocumenting it. In Java one can find out if class implements an interface.The syntax is extremely similar... Not that there is anything wrong withJava syntax.>Take me for example.  If I were a python object, I'd be an instance of a>class that is generalized by two other classes, my mom and dad.  That's my>type, my genetics.class Dad:...class Mom:...class Son (Dad, Mom):...>Now, let's say you were a function that expected a>'Python programmer'.  You could wire that expectation to my implementation>(my class), but then, I'd be the only "kind" of python programmer you could>use.  You could wire it to my generalized classes, but then you could only>use me and my two sisters, and they're not python programmers.Let's say that a programmer does a number of tasks, among them are:'writeRequirements', 'design', 'implement'In that case it is reasonable to expect that every programmer shouldimplement those three methods. In which case I can write code like:# Client codeson = Son ()if has_attr (son, writeRequirements):son.writeRequirements ()if has_attr (son, design):son.design ()if has_attr (son, implement):son.implement ()Assuming that I had interfaces, I would write:interface Programmer:""""""def writeRequirements (self):""""""def design (self):""""""def implement (self):""""""...class Son (Dad, Mom) implements Programmer:...# Client codeson = Son ()if implements (son, Programmer):son.writeRequirements ()son.design ()son.implement ()What are the benefits of using the interface? Documentation is one of thebiggest advantages. Also, an ability to ask the object if it implementsinterface as a whole comes in handy and reduces the number of if statements.Although the version of client code that uses exceptions is as simple.Now let's assume that there is an inexperienced programmer who does notwrite requirements yet, but is capable of doing everything else... It seemslike our interface needs to be split up into two -- Analyst and Programmerinterface Programmer:""""""def design (self):""""""def implement (self):""""""...interface Analyst"""""""def writeRequirements (self):""""""class Son (Dad, Mom) implements Analyst, Programmer:...# New client codeson = Son ()if implements (son, Analyst):son.writeRequirements ()if implements (son, Programmer):son.design ()son.implement ()As you can see the client code had to change.Let's see what would client code withut interfaces look like?# Client codeson = Son ()if has_attr (son, writeRequirements):son.writeRequirements ()if has_attr (son, design):son.design ()if has_attr (son, implement):son.implement ()As you can see, the version with if has_attr() still works just fine!(Assuming that has_attr works...)The point is -- the proposed definition of interfaces brings very little tothe table. Everythinbg it offers can one way or another be done usingexisting language constructs. Sometimes, the use of interfaces introducesbackward-compatibility problems.The biggest benefit that I see in the PEP 245 is the documentation. I likethe fact that documentation will be structured in the form of the interfacedefinition as oppose to a sparate help file.I also like an ability to determine if the object implements interface as awhole. But I can live without it using introspection.If the notion of "__getinterfacereference__" were added, I would see a lotmore value in the PEP.Regards,Alex Shindich-- Posted from mailgw2.itginc.com [38.149.119.13] via Mailgate.ORG Server -http://www.Mailgate.ORG


More information about the Python-listmailing list

[8]ページ先頭

©2009-2025 Movatter.jp