[Road to Intermediate] Understanding Python Properties

Link

[Road to Intermediate] Article Link Summary

Introduction

This is a summary of "** Properties **" that are not covered in Python Tutorial.

I'm currently writing research code in Python, but I've written it properly, so it's messed up. Therefore, I will aim to become an intermediate Python user and aim for code that anyone can read and understand.

What is a property?

What is a property in the first place? The property represents object attribute / property data.

... I don't know.

For example, consider the class Player used in a two-dimensional shooter.

Player instances are for moving and drawing in shooters

--Abscissa x --Vertical coordinates y

I have the information of.

In this way, the attribute / property data of each instance is called ** property **.

Try to implement Player

For the time being, let's implement a normal Player class.

Let's prepare a move function that moves with each coordinate.

The player this time has a movable range of $ 0 {\ leqq} x, y {\ leqq} 500 $ for both $ x and y $.

class Player:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'(x = {self.x}, y = {self.y})'

    def move(self, dx, dy):
        self.x += dx
        self.y += dy


"""
(x = 100, y = 100)
"""
player = Player(100, 100)
print(player)

"""
(x = 0, y = -100)
"""
player.move(-100, -200)
print(player)

The above source code works normally and is simple. However, in terms of object orientation, there are some issues with the above source code.

Problem 1 Encapsulation

The above class can be tampered with ** directly ** property variables.

This is not in very good condition. This is because there is a possibility of setting or changing inconvenient variables.

Also, the basic object-oriented is that the state changes depending on the method.

Problem 2 out of range

I want this Player class to run in $ 0 {\ leqq} x, y {\ leqq} 500 $ for both $ x and y $. However, the move function above caused it to go out of range.

Is it possible to somehow set the process to keep within the range at the same time as setting the variable?

Property

Therefore, we will use Python's notation property.

Let's rewrite the source code as follows.

class Player:
    MIN_X = 0
    MAX_X = 500

    MIN_Y = 0
    MAX_Y = 500

    def __init__(self, x, y):
        self._x = x
        self._y = y

    def __repr__(self):
        return f'(x = {self.x}, y = {self.y})'

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, dx):
        self._x += dx
        self._x = max(0, min(self.MAX_X, self._x))

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, dy):
        self._y += dy
        self._y = max(0, min(self.MAX_Y, self._y))

    def move(self, dx, dy):
        self.x += dx
        self.y += dy


player = Player(100, 100)

player.move(-200, -200)

"""
(x = 0, y = 0)
"""
print(player)

Let's look at the contents one by one.

init

In init, variables are initialized with _x. Variables that you want to handle only internally are often expressed using underscores such as _x.

@property

@property
def x(self):
  return self._x

@property
def External public variable name(self):
return internal variable

Next, let's take a look at x (self). It works like a method, but it can look like a just a variable to the outside of the class. This is for ** returning the value to the outside **.

This is because we use the notation @property ** decorator ** above this function definition. Regarding decorators, I will write another article next time.

For the time being, by adding the keyword @property to the method, you can get the value from outside the class with that method name.

@External public variable name.setter

    @x.setter
    def x(self, dx):
        self._x += dx
        self._x = max(0, min(self.MAX_X, self._x))

    @External public variable name.setter
def External public variable name(self, dx):
        self.Internal variables+= dx
        self.Internal variables= max(0, min(self.MAX_X, self._x))

The @property mentioned earlier was a keyword for getting a value from outside the class and using it.

This means that there is also a keyword that gives a value from the outside and sets the value inside.

Use the keyword @external public variable name.setter. This allows you to set the value internally in the usual notation.

The joy of the property

What is the joy of the property?

In fact, Python properties have a different shape than other languages. Originally I was touching C #, C ++, and Java, so I was quite surprised and uncomfortable.

Python properties are

--For the outside, you can use ** variables as they look ** --For the inside, you can hide important variables and write additional processing.

I am happy to say that.

In other languages

player.setValueA(50);

It had to be described in the form of a function / method, so to speak, it was ** redundant **.

In Python, by using the language specification unique to dynamic languages called decorators, Expose methods like variables to the outside Internally, you can write additional processing.

However, if you write too much complicated content in the setter, it will be a bug and you will have to be aware of it, so it may be necessary to make the content light.

Finally

I summarized the properties! Since I am a beginner, I think there are many mistakes. We would be grateful if you could give us your advice and opinions!

Recommended Posts

[Road to Intermediate] Understanding Python Properties
A road to intermediate Python
[Road to intermediate Python] Use ternary operators
[Road to intermediate Python] Use lambda expressions
[Road to intermediate Python] Article link summary
[Road to Intermediate] Python seems to be all objects
[Road to Python Intermediate] Define __getattr__ function in class
[Road to intermediate Python] Define in in your own class
[Road to intermediate Python] Install packages in bulk with pip
[Python] Road to snake charmer (3) Python class
[Road to intermediate Python] Use if statement in list comprehension
[Road to intermediate Python] Enables comparison operations with original classes
[Road to Python Intermediate] Call a class instance like a function with __call__
[Python] Road to snake charmer (1) Environment construction
Updated to Python 2.7.9
Understanding Python Coroutine
"Backport" to python 2
[Python] Road to a snake charmer (6) Manipulate Pandas
[Road to Intermediate] What are Python's * args, ** kwargs?
How to install Python
Changes from Python 3.0 to Python 3.5
Changes from Python 2 to Python 3.0
Rewrite Python2 code to Python3 (2to3)
How to install python
Introduction to Python language
Introduction to OpenCV (python)-(2)
Introducing Python 2.7 to CentOS 6.6
The road to Pythonista
Connect python to mysql
The road to Djangoist
[Road to intermediate level] Utilize Python's built-in function vars
Road to LPIC-1 acquisition
[Python] Road to a snake charmer (5) Play with Matplotlib
Connect to BigQuery with Python
[2020.8 latest] How to install Python
[python] Convert date to string
Post from Python to Slack
How to install Python [Windows]
Post to vim → Python → Slack
To flush stdout in Python
Convert numpy int64 to python int
python3: How to use bottle (2)
[Python] Convert list to Pandas [Pandas]
Modern Python for intermediate users
Cheating from PHP to Python
Try to understand Python self
Python notes to forget soon
[Python] How to use list 1
The road to download Matplotlib
Connect to Wikipedia with Python
How to update Python Tkinter to 8.6
Post to slack with Python 3
Anaconda updated from 4.2.0 to 4.3.0 (python3.5 updated to python3.6)
Post to Twitter using Python
Start to Selenium using python
Introduction to serial communication [Python]
Update python on Mac to 3.7-> 3.8
3 Reasons Beginners to Start Python
Convert Scratch project to Python
Paiza Python Primer 8: Understanding Classes
Python: How to use pydub