Q:

Do instance variables declared outside of `__init__()` have any differences in python?

I'm wondering weather it is necessary to define class instance variable within class declarations. 
I tried assigning a new instance variable after the object (class instance) was already created, and looks like there is no difference. Are there any caveats in this approach?
class Context():
    def __init__(self, extension):
        self.extension = extension

c = Context('extension+')

print(f"before: {c.__dict__}")

c.new_var = 'new_var_content'
print(c.extension + c.new_var)

print(f"after: {c.__dict__}")

printed:
before: {'extension': 'extension+'}
extension+new_var_content
after: {'extension': 'extension+', 'new_var': 'new_var_content'}

A:

There is no difference between declaring self.foo within a def __init__(self, <arguments>): definition, and declaring it after an object has been instantiated.  
Both assignments have instance-level scope. 
Given -
class Context:
    i_am_a_class_variable = 'class_string'
    def __init__(self, bar):
        self.bar = bar

See - 

class attributes can be accessed without instantiating an object.

>>> Context.i_am_a_class_variable
'class_string'

instance attributes can be assigned during instantiation using the __init__(self) function. 

>>> Context.bar
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-8be0704da5be> in <module>                                 
----> 1 Context.bar
>>> instance = Context('bar')
>>> instance.bar
'bar'

instance attributes can be assigned after instantiation, directly

>>> instance = Context('bar')
>>> instance.foo = 'foo'
>>> instance.foo
'foo'

