Classes in Python

Tram Ho

Today, I continue to learn about you “Class (class) in python”, the next blog post is in the series “Explore Python Citadel” (content in this series is mainly from python.org and then write re-translate or re-translate in your own language)

In this article, we will learn more about how to create and use these object classes and related concepts.


Classes are quintessential in Python, so it has the incredibly powerful power of allowing us to group the fields and related functions together to create a kind of factory. where an infinite number of instances can be produced.

You can visualize the class as a blueprint for a certain type of object, like a home blueprint, from this blueprint you can create different entities, which are different houses. together.

However, before learning about classes, there are two concepts that are namespaces, scope and a rule called LEGB you need to know to understand why the program, understand why the class works like that. This knowledge is quite abstract and has a lot of content, so I have separated them into a separate post called “namespace and scope in Python” , please read and then come back. Let’s go to class.

5 minutes passed,… hope you have read all the above articles, you can lie to me not to lie to myself =)) Okay, it’s time for me to cover today’s main content.

First appointment with Chess

While I was dating with Python, I got to know Chess guy, he’s a close comrade of my family with Python. Python has told me a lot about this friend, there are a lot of cool new things, let’s go explore Chess with me.

This is what he looks like

The flag told me, he is the type of person who reads the manual carefully before using it, erroneously, he is the type that needs to be defined before use , and must be defined with the keyword ” class “.

Once he is used, a namespace is initialized , and it is used as a local scope, which contains all the variables declared in him.

Sounds good. So how is it specifically?

Well, in particular, for example a function defined in him, the name of this function will be in the other namespace, and I can use it from him. Once he has been defined (ie all the <command-N> above), an object class is instantiated . This object class will essentially wrap all elements of the namespace created by this class definition (more on this section).

Roughly this is the local scope of the class that will turn on the game mode as soon as his name is used and the class object here is associated with the class name he gets in the title after the word class when defined. There, here is the word “TenCuaLop” .

He is the class of objects

Chess also told me, everyone who knows him knows that he has two strong points:

– know myself

– know how to create his own life

Know yourself

Knowing himself is that he knows how to attribute references available in him.

The way he uses it often, is the way Python shows him, is to use the “.” to refer to attributes by myself, for example obj.name . Therefore, if Chess is defined like this:

MyCoLat. ten , MyCoLat. say_hi are reference properties, return the value of a string (ten), and a function (say_hi).

His properties are also assignable, so I can change its value. In addition, doc is also an attribute, it will return the value of the description “Class of BeautyOnCode”, this is his default property.

Create your own life

To initialize his own life, my Banner will turn on the ” call function ” mode, but for now the function takes no parameters and will return a new instance of himself.

The line above is my Banner, which has been initialized to a new entity called “co_lat_empty”, at this point my “co_lat_empty” is completely empty.

Oh, so your Banner transforms, or is it multi-personality? Yes, that’s it, you see quickly, My Chess is the ultimate multi-personality type.

In every situation, or in every context, he can transform into completely different people. And yet, he also has a secret to creating his own life, such as going to the beach, he will wear swimsuits, go to the temple to wear pants, wear a hat in the sun, wear a hat in rain. raincoat, …

And, his Doraemon bag, it’s the init function.

Let’s see how this function helps my Banner transform:

When my Banner holds this function, for each version of his transformation, his brain will automatically call through this function to initialize the attributes that are the traits and characteristics he wants.

And yet, just a thought in the mind as an input form is that this function can have different values. Here is my improved Lat Flag with the init function

For example, when he wants to hang out with me, he will create a version of himself like this:

See, you guys must also understand, right, hihi. My paved friend will transform into the handsome_like “Lee Min Ho” with 10 years of love_expensive experience.

That’s when he thinks about and puts specific values ​​in to transform, but when he’s lazy, he doesn’t have to put anything in, defaults to as handsome as ‘HyunBin’ and has 5 years of love. there (he is no longer empty like before).

Ui, so I like him completely, too cool, isn’t it ^^.

Revisions of the object

You guys know my Banner can reference properties and initialize it. What about his transitions to do?

His entity versions support only one “attribute reference” activity , meaning that each of them knows its own characteristics very well and knows how to access them.

These features can be divided into two categories:

Identifying characteristics

His own character, also known as the attribute data (data attributes)

Data properties are not declared, like local variables, and they begin to exist since they are assigned.

For example, since x is an instance of MyCoLat above, I create a data property for it called “counter”, it begins to exist at the time I assign the value and can use it right after that.

Actions

As for the actions of each version as seen girls as auto lemon or see adults is polite auto modes (methods).

The object’s method is a function that belongs to that object.

The names of an object’s methods depend on the object’s class. By definition, all properties of the class that represent the actions of the objects are used by the method to perform.

In our example, xf is a valid f method reference, because MyCoLat.keep_it is a function.

But MyCoLat.handsome_like is not a method reference, because handsome_like is just a data property.

** What about x.keep_it and MyClassDating.keep_it are the same? **

These two are different, okay?

– with x.keep_it, keep_it is the method of the entity x

– with MyCoLat.keep_it, keep_it is the method of the MyCoLat object

Actions of objects

My flag can create multiple instances of him, and he can also create general actions for these instance types.

As above, keep_it is such a method, this method can be called immediately or can also be assigned a value for later use.

– When calling from the x entity, I call x.keep_it ()

– When you want to assign to the value you assign: y = x.keep_it, and can use this y as a normal variable.

** So what happened when the method was called like this x.keep_it ()? **

You can see that x.keep_it () is called without a variable, even if keep_it is defined with a self variable.

Why is it possible? Something’s wrong, is there a lack of variables? If Python is missing, it screams the error of missing variables, man, even if this variable you don’t use, Python will still require it, called required args, but there is absolutely no error here. Come on, it’s weird.

Actually, I believe you have already math your answer: there is a special point right where this method is the entity that calls the method which will be automatically inserted into that self variable. In the example, when I call x.keep_it (), it will be equivalent to calling like this MyCoLat.keep_it (x) .

In general, calling a method from entities with variables is equivalent to calling that method from its class plus the same entity passed in the first position, representing that entity. .


If you still don’t understand, you can take a look at how the class executes.

For example, when a property that is not private data of x is referenced, here is keep_it (it’s of the flag), the program will go looking for it in the class of x, that is, it jumps in MyCoLat you find, and it recognizes that keep_it is the method of the object class (keep_it of MyCoLat), so it creates a new method object by encapsulating x with that function , leaving them to Together, create an abstract object which is the method of the object (keep_it of x).

When x calls this method together with an argument list, a new argument list is built including the calling entity and its associated argument list, and then it calls the method of the above object using the arguments. This new issue.

Hope you will understand

Flag Properties and Instances Properties

In general, the personality of the flag, the versions are inherited, and the personality of each version is only its own version.

Here is an example:

As I can see above, ” kind ” is a shared attribute. With such shared properties, if it is mutable data types such as list, dict, it will likely create many unexpected cases because of this shared nature.

For example, I add another attribute describing the interests of dogs as “interest”, which is a dict:

So, when “interest” is a common property that is shared with all other versions, will it cause problems?

So here, I need to put this “interest” in for each version one by one, by putting this property in the init function, so this property will be initialized for each version separately, like this will acting as expected is v only has one interest is [“sleeping”] nè:

A few more notes

The flag and version have the same attribute name, the instance name is preferred

If the same property name is present in both the entity and the entire object class, the entity property will take precedence.

Here, after I create a version of x, I have a dog friend named “Beck” and then I assign the variable kind to the value “foreign dog”, then this kind of x will have this new value.

Some principles of semantics

The first variable of a method in the class will usually start with self (as I learned above).

So, if I don’t have self, can I?

The answer is yes. However, this is the semantic rule of class in Python, so even though I can write it, I am as limited as possible, because it will cause misunderstandings with others.

How about I can put the code of the methods outside the code of the class?

The answer is OK, because no one has to put it on top. People often put it inside for easy reading.

Call the function

You can call a function in the same class as self

This method can call another method in the same object class, use self to call.

The following example calls the add function twice in the addtwice function:

Call the method of the object class

Methods in a class can refer globally just like regular functions, with the global scope associated with the method being the module containing its definition. For example, I can call Bag’s add function like this: Bag.add (1)

But the object class is never used as a global scope. While there is rarely a reason for using methods of a class globally, there are more reasonable uses of the global scope: for example, functions and modules loaded in the scope. en global to be used in methods, as well as in the definition of functions or classes in the global scope.

Usually, the class contains methods defined in the global scope, and in the next section we’ll find a few more reasons why the method references its own class.

Each value is an object, and therefore will have a class (also known as its type), stored as object object. class .

Inheritance

When it comes to classes, of course inheritance, as this is the diamond in object oriented programming.

To inherit a class is very simple, just wrap the class you create with the class you intend to inherit, it will be like this:

The base class BaseClassName must be defined in the scope that contains the derived class DerivedClassName. In the BaseClassName I also allow some other forms such as calling that class from some module, for example: class DerivedClassName (modname.BaseClassName):

Execution of a derived class definition is performed in the same way as the base class. When the object class is instantiated, it remembers its base class . This will be used to deal with property references: if a requested property is not found in the derived class, it will go looking for it in the base class . This rule is applied recursively if the base class itself is a derived class from other base classes as well.

Creating a new instance from the derived class is similar to what I learned: DerivedClassName (). Reference methods are handled as follows: the corresponding class property is searched, delving into the base classes if necessary, and the reference method valid if the process returns a function object. .

Derived classes can override the methods of their base classes. Since methods have no special privileges when calling other methods of the same object type, a method of the base class that is allowed to call another method defined in the same base class may end with Calling a derived class method overrides it.

An overridden method in the derived class may be more extensive than just replacing the base class’s method of the same name. A simple way to call methods from the base class directly is to call BaseClassName.methodName (self, argument).

Python provides two built-in functions for working with this inheritance:

Use isinstance () to check the type of entity : isinstance (obj, int) will return True only if obj. class is int with class derived from int

Use issubclass () to check for inheritance : issubclass (bool, int) is True when bool is a subclass of int. However, issubclass (float, int) is False because float is not a subclass of int.

Inherited from many classes

Python also supports the inheritance of many more classes.

So how is inheritance done here?

For most purposes, in the simplest cases, you might think that finding properties inherited from the parent class is searching in depth, from left to right, and not searching. twice in the same class where there is an overlap in the hierarchy.

Therefore, if a property is not found in DerivedClassName, then it looks in Base1, then recursively looks in Base1’s base classes, and if not found it looks in Base2, and so on. until the end.

In fact, it’s more complicated than that, the order in which the methods are resolved dynamically to support cooperative calls to super ().

Automatic ordering is necessary because all instances of multiple inheritance exhibit one or more closely related relationships (where at least one of the superclasses can be accessed via multiple paths from bottom layer).

For example, all classes inherit from the object, so any multiple inheritance instances provide a path to reach the object. To keep the base class from being repeatedly accessed, a dynamic algorithm that linearizes the search order in a way that preserves the order from left to right is assigned to each class, calling the superclass only once, and that is monotonous (meaning a class can be subclassed without affecting the precedence of its superclass). Taken together, these properties make it possible to design reliable and extensible classes with multiple inheritance. For more details you can read more here

Private variables

“Private variables cannot be accessed unless it is accessed from within an object”, which does not exist in Python, like other object-oriented languages .

However, there is a convention: a prefix of an underscore (e.g. _spam) can be interpreted as an undisclosed part of the API (it can be a function, a method, or a data variable. ), and such components are considered subject to change without notice.

One common case of using private variables is to avoid name collisions when we both define that name in a subclass. Therefore, there is a mechanism to support the above conflict, called the name mangling (“name mangling”), with the definition in the form of two underscores __spam , which will be replaced with __classname__spam , this classification is irrelevant to the syntactic position of the identifier, as long as it is within the class definition.

Such a name classification is quite useful while overriding the methods of the superclass without disturbing the other methods that are called. For example:

In the above example, I see the line assigned __update = update in the Mapping class is the implementation of classifying the name __update of this class, which is Mapping__update (you call Mapping.__dict__ will see this variable).

So, even though the update method is overridden in the MappingSubclass subclass, the init method still works normally without being affected.

Even if I write a separate __update method of __update class, the code can still work, because its method is called _MappingSubclass__update at this time.

Really good, isn’t it?

On a side note, such discriminatory principles are designed to avoid unexpected situations. It is possible to access and modify a private variable. This can be useful in a situation where you need to debug something.


Sometimes, I just need an empty class to then assign specific attribute values ​​to:

A method of an object instance also has its own properties. For example, I create a mapping = MappingSubclass ([]) entity, then mapping.update is its a method, and mapping.update. self is the mapping entity, and mapping.update. func is the update function of that entity.


Although there is a piece of content about iterators and generators, but the article about the class has been quite long, I will win these two friends in the next post, and will study and write more carefully.

Thanks for reading,

Original post in my own blog, please come and play.

BeautyOnCode.

Share the news now

Source : Viblo