Python: A Note About Classes 1 "Abstract"

Summary: From how to use parts to how to combine

We will not only use program fragments, but also proceed with learning toward the implementation of programs that combine them.

Current status

Thanks to the extensive library and commentary, I managed to realize the little idea that I wanted to do and that I wanted to do. On the other hand, if you try to combine them to make one program, the whole thing will be messed up and you will not be able to handle it.

Therefore, here we will organize what we have learned about the class and summarize various matters for the purpose of creating a "program that can be expanded and maintained by ourselves". As a programmer who is still a beginner, advice is welcome.

Class abstraction

Set the level of abstraction appropriately

Naming is important in the program. If you give it an appropriate name, it will hinder your understanding and recognition. Therefore, the degree of abstraction must be determined according to the situation in order to get a firm grasp of what is going on.

Abstraction

If you search for "Python class abstraction", most of the information is about how to use metaclasses. This is a part that was unexpectedly difficult to understand.

As an example, imagine the situation of making a classic Western fantasy role-playing game. What kind of name should we give when creating a class that deals with one character, John, a villager?

First of all, as a premise, various things in the world belong to multiple groups at the same time. Of course John is no exception.

概念図.png

There are a number of names that John can give, just for a quick glance. An Object that is all objects (grounds, trees, buildings, characters, etc.) that exist in the game. Creature is a living thing among living things and inanimate objects. Humanoid, a humanoid creature that may include elves and dwarves as well as ordinary people. As a result of endlessly tracing among the humanoid creatures, we arrive at John, a villager.

Too high level of abstraction

When it comes to "Would you like to make Creature for living things for the time being?", I think the implementation will be as follows.

creature.py


class Creature:
    def __init__(self, hp, mp, start_position, area):
        self.hp = hp
        self.mp = mp
        self.position = start_position
        self.area = area
        self.oxygen = 100
    
    def move(self, next_position):
        if self.area == "land":
            self.walk()
            self.position = next_position
        
        elif self.area == "water":
            self.swim()
            self.position = next_position
        
        elif self.area == "sky":
            self.fly()
            self.position = next_position
    
    def walk(self):
        print("Teku Teku")

    def swim(self):
        print("Sui")
    
    def fly(self):
        print("Byun")

Since it is a group called Creature, it will be necessary to separate at least the creatures that live on the ground, the creatures that live underwater, and the creatures that live in the air. Considering that the creatures living on the ground enter the water, I feel that I have to manage the amount of oxygen. Weight management seems to be important for creatures living in the air.

Furthermore, since we are thinking about a fantasy world this time, there is a possibility that some creatures will live in the demon world contaminated with miasma, and some will live in the ground where there is no light. Along with that, it can be expected that the number of things to be implemented will increase at an accelerating rate, such as different movement methods and setting unique status.

Too low abstraction

If you think, "Aside from the rest, do you want to keep it as a villager?", I think the implementation will be as follows.

villager.py


class Villager:
    def __init__(self, name, hp, start_position):
        self.name = name
        self.hp = hp
        self.position = start_position
    
    def move(self, next_position):
        self.position = next_position
        print("Teku Teku")
    
    def speak(self, line="Hello. This is the beginning village"):
        print(f"{self.name}「{line}」")

villagerA = Villager("John", 100, [0,0])
villagerA.speak()
villagerA.speak("Where did you come from?")

#Execution result
'''
John "Hello. This is the village of the beginning."
John "Where did you come from?"
'''

It's different from the previous one, and it's only for villagers, so it's easy to think about what to implement. If you treat it as an NPC, you should wander around it appropriately, and when you talk to it, speak the appropriate lines.

On the other hand, there is a desire to implement it neatly. For example, when considering creating a walled city and placing NPCs there, this Villager seems to be used with a little tinkering. The basic function of moving and talking remains the same.

Considering the expandability later, it seems that the name Villager is not the best. Try subdividing the living area, or add characteristics to each living area. It's an extension like making a child who can't attack to give variation, or a rogue who can attack on the contrary.

Appropriate level of abstraction

So what is a name with the right level of abstraction that is neither too high nor too low? It can change as much as you like depending on the specifications, but the reasonable points are as follows.

resident.py


class Resident:
    def __init__(self, name, hp, start_position):
        self.name = name
        self.hp = hp
        self.position = start_position
    
    def move(self, next_position):
        self.position = next_position
    
    def speak(self, line="Hello"):
        print(f"{self.name}「{line}」")

citizenA = Resident("John", 100, [0,0])
citizenA.speak()
villagerA = Resident("Mary", 100, [0,10])
villagerA.speak("Hello. Is this South City?")

#Execution result
'''
John "Hello"
Mary "Hello. Is this a South City?"
'''

I named it Resident because it lives somewhere. This includes villagers and citizens. It may be okay to create an aerial city citizen.

Summary

The higher the level of abstraction, the more things to implement. Taking a vehicle as an example, if you try to implement it as Transportation instead of Car, it will include airplanes and ships, and the amount of implementation will increase again.

On the other hand, lowering the level of abstraction reduces the amount of work to be implemented, but naturally narrows the range of use. Similarly, taking a vehicle as an example, implementing Bus instead of Car will narrow the scope of consideration and make implementation easier. On the other hand, considering the application to Taxi, which also carries customers, it will take another time and effort.

--If the level of abstraction is too high, there will be more things to implement. ――If the level of abstraction is too low, it will take time and effort to reuse it for others.

Digression

From the next time onward, we plan to summarize abstract base classes and inheritance and synthesis / delegation.

Recommended Posts

Python: A Note About Classes 1 "Abstract"
A note about [python] __debug__
A note about mock (Python mock library)
A note about __call__
A note about subprocess
A note about mprotect (2)
A note about the python version of python virtualenv
Data analysis in Python: A note about line_profiler
About python objects and classes
A note about KornShell (ksh)
A memorandum about correlation [Python]
A note about TensorFlow Introduction
A memorandum about Python mock
A note about hitting the Facebook API with the Python SDK
A note about get_scorer in sklearn
What was surprising about Python classes
Note: Python
[Python] About Executor and Future classes
Python note
A note where a Python beginner got stuck
A Java programmer studied Python. (About type)
A story about Python pop and append
Talking about old and new Python classes
About February 02, 2020 * This is a Python article.
A note about doing the Pyramid tutorial
About python slices
About python comprehension
Python study note_002
Note: Python Decorator
Python programming note
[Python] Learning Note 1
About Python tqdm.
About python, class
Python study note_004
About python inheritance
About python, range ()
Python study note_003
About python decorators
[Note] openCV + python
Note about awk
Just a note
About python reference
About Python decorators
[Python] About multi-process
Python beginner's note
A Java programmer studied Python. (About functions (methods))
A Java programmer studied Python. (About the decorator)
[Note] Create a one-line timezone class with python
A note on optimizing blackbox functions in Python
A memo about writing merge sort in Python
A simple Pub / Sub program note in Python
Python Note: When assigning a value to a string
A story about running Python on PHP on Heroku
Think about building a Python 3 environment in a Mac environment
A memorandum about the Python tesseract wrapper library
[Note] About the role of underscore "_" in Python
A note about the new style base class
A note about checking modifiers with Max Plus
A story about modifying Python and adding functions
About Python for loops
Summary about Python scraping