[Python-projects] Type inference not working?

Maarten ter Huurne maarten.ter.huurne at philips.com
Thu Jan 24 15:35:56 CET 2008


syt at logilab.fr wrote on 2008-01-24 08:41:31 AM:

> On Wed, Jan 23, 2008 at 08:01:33PM +0100, Maarten ter Huurne wrote:
> > The way I want to use it is by having a factory method like this:
> > ===
> >     @staticmethod
> >     def create(data):
> >         instance = SomeClass()
> >         instance.__setSomething(data)
> >         return instance
> > ===
> >
> > I want to have several ways of instantiating the same class and doing
it all
> > using different constructor arguments would be messy.
>
> Why not simple instance = SomeClass(data) with SomeClass'__init__
> calling __setSomething(data) ?

Because I don't always want to call __setSomething.

The object I'm constructing is a data structure that can be serialized to
XML. It's similar to Nevow's Stan.

There are three scenarios for constructing an XML sequence:
A. empty sequence
B. copying children from an iterable that contains only XML-serializable
objects
C. copying children from an iterable that contains objects whose state can
be converted to XML-serializable objects

To differentiate between case A and B, I can simply use "children = None"
as a default parameter value. However, to differentiate between B and C in
the constructor would be difficult. Since case B is a subset of case C, it
would be correct to simply handle only case A and C, but it would be a
waste of performance in case B where I know that all objects are
XML-serializable. So I created a static method which creates an empty
sequence and then adds the children using a private method that does the
conversion.

> > What I'd like to do is call a private instance method from a static
method in
> > the same class. This is flagged as a warning, which could mean:
> > - PyLint considers this as something that is not OK (why?)
> > - PyLint doesn't know that the instance is of the same class that the
static
> > method belongs to (my guess)
>
> no, this time, pylint is right ;) You're actually calling the private
> method on an instance outside the class code definition (eg to simplify,
> you're only allowed to call private method using "self" inside a method
> of the class). You're 2nd point doesn't make sense: when you're calling
> a method (static or not) on an instance, the instance should always be
> of the same class (or derived of) as the method's class...

I think that simplification is exactly the issue here: it is possible for
an object to be a guaranteed instance of the class that contains a piece of
code without that object being "self".

Here is a slightly modified version of the example:
===
class SomeClass(object):

    def __m(self):
        pass

    @staticmethod
    def s():
        obj = SomeClass()
        obj.__m()

SomeClass.s()
===

Inside method s(), obj is guaranteed to be an instance of SomeClass. Since
the method s() making the call is a member of SomeClass and the method
__m() being called is also a member of SomeClass, in my opinion calling the
private method should be allowed. For example in Java it would be allowed
as long as obj has the static type SomeClass.

Another example:
===
class Text(_XMLSerializable):

    ...

    def __cmp__(self, other):
        # pylint: disable-msg=W0212
        return not isinstance(other, Text) \
            or cmp(self.__text, other.__text)
===

Here for the evaluation of the expression "other.__text", it is guaranteed
that "other" is an instance of Text, so accessing the private field should
be allowed, in my opinion.

(Note: Python is so dynamic that very little comes with hard guarantees;
for example someone could override SomeClass.__call__ to return objects of
a different type, but that would be considered bad in itself.)

Bye,
            Maarten
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.logilab.org/pipermail/python-projects/attachments/20080124/8cf70118/attachment.htm 


More information about the Python-Projects mailing list