Python define variable type in class

In general, this is not a good idea for the reasons that @yak mentioned in his comment. You are basically preventing the user from supplying valid arguments that have the correct attributes/behavior but are not in the inheritance tree you hard-coded in.

Disclaimer aside, there are a few of options available for what you are trying to do. The main issue is that there are no private attributes in Python. So if you just have a plain old object reference, say self._a, you can not guarantee that the user won't set it directly even though you have provided a setter that does type checking for it. The options below demonstrate how to really enforce the type checking.

Override __setattr__

This method will only be convenient for a (very) small number of attributes that you do this to. The __setattr__ method is what gets called when you use dot notation to assign a regular attribute. For example,

class A:
    def __init__(self, a0):
        self.a = a0

If we now do A().a = 32, it would call A().__setattr__('a', 32) under the hood. In fact, self.a = a0 in __init__ uses self.__setattr__ as well. You can use this to enforce the type check:

 class A:
    def __init__(self, a0):
        self.a = a0
    def __setattr__(self, name, value):
        if name == 'a' and not isinstance(value, int):
            raise TypeError('A.a must be an int')
        super().__setattr__(name, value)

The disadvantage of this method is that you have to have a separate if name == ... for each type you want to check (or if name in ... to check multiple names for a given type). The advantage is that it is the most straightforward way to make it nearly impossible for the user to circumvent the type check.

Make a property

Properties are objects that replace your normal attribute with a descriptor object (usually by using a decorator). Descriptors can have __get__ and __set__ methods that customize how the underlying attribute is accessed. This is sort of like taking the corresponding if branch in __setattr__ and putting it into a method that will run just for that attribute. Here is an example:

class A:
    def __init__(self, a0):
        self.a = a0
    @property
    def a(self):
        return self._a
    @a.setter
    def a(self, value):
        if not isinstance(value, int):
            raise TypeError('A.a must be an int')
        self._a = value

A slightly different way of doing the same thing can be found in @jsbueno's answer.

While using a property this way is nifty and mostly solves the problem, it does present a couple of issues. The first is that you have a "private" _a attribute that the user can modify directly, bypassing your type check. This is almost the same problem as using a plain getter and setter, except that now a is accessible as the "correct" attribute that redirects to the setter behind the scenes, making it less likely that the user will mess with _a. The second issue is that you have a superfluous getter to make the property work as read-write. These issues are the subject of this question.

Create a True Setter-Only Descriptor

This solution is probably the most robust overall. It is suggested in the accepted answer to the question mentioned above. Basically, instead of using a property, which has a bunch of frills and conveniences that you can not get rid of, create your own descriptor (and decorator) and use that for any attributes that require type checking:

class SetterProperty:
    def __init__(self, func, doc=None):
        self.func = func
        self.__doc__ = doc if doc is not None else func.__doc__
    def __set__(self, obj, value):
        return self.func(obj, value)

class A:
    def __init__(self, a0):
        self.a = a0
    @SetterProperty
    def a(self, value):
        if not isinstance(value, int):
            raise TypeError('A.a must be an int')
        self.__dict__['a'] = value

The setter stashes the actual value directly into the __dict__ of the instance to avoid recursing into itself indefinitely. This makes it possible to get the attribute's value without supplying an explicit getter. Since the descriptor a does not have the __get__ method, the search will continue until it finds the attribute in __dict__. This ensures that all sets go through the descriptor/setter while gets allow direct access to the attribute value.

If you have a large number of attributes that require a check like this, you can move the line self.__dict__['a'] = value into the descriptor's __set__ method:

class ValidatedSetterProperty:
    def __init__(self, func, name=None, doc=None):
        self.func = func
        self.__name__ = name if name is not None else func.__name__
        self.__doc__ = doc if doc is not None else func.__doc__
    def __set__(self, obj, value):
        ret = self.func(obj, value)
        obj.__dict__[self.__name__] = value

class A:
    def __init__(self, a0):
        self.a = a0
    @ValidatedSetterProperty
    def a(self, value):
        if not isinstance(value, int):
            raise TypeError('A.a must be an int')

Update

Python3.6 does this for you almost out-of the box: https://docs.python.org/3.6/whatsnew/3.6.html#pep-487-descriptor-protocol-enhancements

TL;DR

For a very small number of attributes that need type-checking, override __setattr__ directly. For a larger number of attributes, use the setter-only descriptor as shown above. Using properties directly for this sort of application introduces more problems than it solves.

How do you define a variable in Python class?

In Python, Class variables are declared when a class is being constructed. They are not defined inside any methods of a class because of this only one copy of the static variable will be created and shared between all objects of the class.

Can you define a variable in a class?

A class variable is an important part of object-oriented programming (OOP) that defines a specific attribute or property for a class and may be referred to as a member variable or static member variable.

Can you specify variable type in Python?

Specify a Variable Type Casting in python is therefore done using constructor functions: int() - constructs an integer number from an integer literal, a float literal (by rounding down to the previous whole number), or a string literal (providing the string represents a whole number)

What are the types of variables in class in Python?

Inside a class, we can have three types of variables..
Instance variables (object level variables).
Static variables (class level variables).
Local variables..