0

I'm not very familiar with Python, so when I met this code, there are a few things not quite clear to me. Here is the code:

class TypeVariable(object):
    #A type variable standing for an arbitrary type.
    #All type variables have a unique id, but names are only assigned lazily, 
    #when required.

    next_variable_id = 0

    def __init__(self):
        self.id = TypeVariable.next_variable_id
        TypeVariable.next_variable_id += 1
        self.instance = None
        self.__name = None

    next_variable_name = 'a'

    @property
    def name(self):
        #Names are allocated to TypeVariables lazily, so that only TypeVariables present
        if self.__name is None:
            self.__name = TypeVariable.next_variable_name
            TypeVariable.next_variable_name = chr(ord(TypeVariable.next_variable_name) + 1)
        return self.__name

Why does def __init__(self): not have name as a parameter but in the above code there is self.__name = None?

Also, what does self.instance mean, because I don't recall that there is an attribute called instance.

Can someone please help me understand what this code does, and if a java version can be provided will be much appreciated since I'm more familiar with Java. Thanks

2 Answers 2

3

The code has no context to say what self.instance might be. As for self.__name, the property definition makes clear that it is lazily assigning sequential names to instances. It sets __name to None so it knows it hasn't been initialized; when self.name is accessed, it will recognize the placeholder, replace it with a new value, and return the new value.

Note that providing some assignment to all instance attributes in __init__ is considered good form in Python, since otherwise it can be very hard to figure out what attributes an instance might have. And in modern Python (3.3 and up), doing so gets you a memory savings; as long as all attributes are initialized in __init__ and no new attributes are added after __init__, the __dict__ for all instances is a key-sharing dictionary which reduces the cost of each instance significantly (by roughly two-thirds, though that's an implementation detail). So if some other method/property would set instance later, it's best to initialize it to something in __init__ both for maintainers to know what it's supposed to have, and reduced memory consumption in Py3.3+.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi, can I consider the def __init__(self) as a constructor in Java, if so then how come it can do add operation in the constructor
@AndaZhao: Technically, __init__ is an initializer; the raw object is created before it is called (that's how you receive self). Python has a __new__ that constructs (and can initialize too), but it's typically only used for logically immutable objects (__init__ can be called more than once, which would violate immutability) or cached/singleton objects (__new__ can return an existing object, not just make new ones). But in any event, Python, unlike Java, doesn't define instance attribute names ahead of time in general; you can define any attribute, any time.
0
self.instance = None
self.__name = None

There are just object attributes with default value. You don't need to put them into __init__() parameters if they are not required for building class instance.

1 Comment

self.__name is needed at the least since the @property assumes it exists. The implementation of name would have to change if it wasn't guaranteed to be initialized in __init__.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.