With the accumulation of programming experience in the same language, we all develop the standard programming techniques for ourselves. The higher our experience, the greater the number, the more diversified their working methods. When switching to another language, we try to reproduce them. Sometimes, it happens that some of them are irrelevant or ineffective. Most of the time from learning a new language, alien to the former us, methods are taken away. I would like to point out some features of Python that were not obvious to me at first.
By and large, in python, all objects are stored in dictionaries (dict). A dictionary is a list of objects that is opposed to a key that is unique to the entire dictionary.
class A(): i=1; s='string'
print dir(A)
> ['__doc__', '__module__', 'i', 's']
This property allows you to "get up" with classes and instances of classes a variety of things. For example:
class A(): v0=1
class B(A):
v1=2
def __init__(self):
self.v2 = 3
b=B()
print b.v2, b.v1, b.v0
> 3 2 1
When Python tried to get v2 everything is clear - it is obtained from the dictionary of the instance b. Further interesting, the property v1, no longer contains the element b, it contains the dictionary B - the python took it from there. And, finally, when searching for the element v0, we turn to the dictionary of the parent BA, and retrieve it from there. It is clear that if we determine the property v0 within b, then its value will be obtained from there, without rising to higher levels.
')
def __init__(self):
print self
class A(): pass
setattr(A, '__init__', __init__)
a=A()
> <__main__.A instance at 0x009E9EB8>
In this example, we moved the function __init__ to the limits of class A (we could move the function with any other name, __init__ is given for clarity). Class A declaration is equivalent to:
class A():
def __init__(self):
print self
Classes in python are instances of metaclasses. This is a surprise, because now you are allowed to define classes on the fly, not just their instances.
def __init__(self):
print self
B = type('B', (), {})
setattr(B, '__init__', __init__)
b = B()
>
<__ main __. B object at 0x009E7CD0>
Note that a function is defined only for instances of a class; it cannot be called for class A itself. On the other hand, what prevents us from adding this opportunity.
def Omd(obj):
print obj
B = type('B', (), {})
setattr(B, 'c', classmethod(Omd))
setattr(B, 'o', Omd)
b = B()
bc(), bo()
>
<class '__main __. B'>>
<__ main __. B object at 0x009E7D50>Fun true ?! We determined the function that prints its first argument. Next, we created a class based on the metaclass (it was possible to define it as standard, as
class A(type): pass
). Next to the class, we added a static function ācā, under which ours is hidden, and a function āoā to call it from an instance of class B. We look at what happens, first we see that the class is printed, and after it is an instance. Here is such a love.