[PYTHON] I did a little research on the class

Since I'm almost a beginner in python, I'll first look at the class (something like a habit) with simple code.

class sampleCls():
	pass

Define an empty class. If you try to output the members of the class in this state,

from pprint import pprint

class sampleCls():
	pass

pprint (inspect.getmembers(sampleCls))

When executed,

[('__doc__', None), ('__module__', '__main__')]

Like this.

Add one line (instead of pass).

class sampleCls():
	abc = 111

pprint (inspect.getmembers(sampleCls))

When executed,

[('__doc__', None), ('__module__', '__main__'), ('abc', 111)]

Like this.

After passing the class definition, a class object is created. Class objects can be modified. Try modifying the class object without instantiating it yet.

class sampleCls():
	abc = 111

#sampleCls.def = 222
sampleCls.efg = 222
pprint (inspect.getmembers(sampleCls))
[('__doc__', None), ('__module__', '__main__'), ('abc', 111), ('efg', 222)]

You can change it like this. (In sampleCls.def, def is a reserved word and an error occurs (; ´∀ `))

If you create an instance of this class in this state,

class sampleCls():
	abc = 111

sampleCls.efg = 222
i = sampleCls()
pprint (inspect.getmembers(sampleCls))
print "------------------------------"
pprint (inspect.getmembers(i))
[('__doc__', None), ('__module__', '__main__'), ('abc', 111), ('efg', 222)]
------------------------------
[('__doc__', None), ('__module__', '__main__'), ('abc', 111), ('efg', 222)]

With that feeling, the efg added later is also included in the instance. By the way, you can also delete variables from the class object.

class sampleCls():
	abc = 111

sampleCls.efg = 222
pprint (inspect.getmembers(sampleCls))
print "------------------------------"
del sampleCls.abc
pprint (inspect.getmembers(sampleCls))

When executed,

[('__doc__', None), ('__module__', '__main__'), ('abc', 111), ('efg', 222)]
------------------------------
[('__doc__', None), ('__module__', '__main__'), ('efg', 222)]

It's gone. This area is similar to JavaScript.

There is no constructor

The site below says that python doesn't have a constructor.

Also, such a thing was written in the book. [* 1](# 1) </ sub> As for the definition of the constructor, it seems that memory allocation is also done by the constructor.

From the standpoint of programming, memory allocation is built into the language, so instances can be initialized, so I thought it would be okay to think of init as a general constructor. Regarding \ __ new__, it seems a little different, so I'll write a little more next.

What is \ __ new__?

First, let's write a simple code.

class sampleCls(object):
	abc = 111
	print "chkpnt10"
	def __new__(cls):
		cls.efg = 777
		print "chkpnt20"
		return super(sampleCls, cls).__new__(cls)
	def __init__(self):
		self.hij = 999
		print "chkpnt30"

pprint(dir(sampleCls))

When you do this,

chkpnt10
['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'abc']

chkpnt10 is output, but chkpnt20 and chkpnt30 are not displayed. Neither efg nor hij is included in the class object dump. What happens when you create an instance?

class sampleCls(object):
	abc = 111
	print "chkpnt10"
	def __new__(cls):
		cls.efg = 777
		print "chkpnt20"
		return super(sampleCls, cls).__new__(cls)
	def __init__(self):
		self.hij = 999
		print "chkpnt30"
i = sampleCls()
pprint (inspect.getmembers(sampleCls))
pprint (inspect.getmembers(i))
chkpnt10
chkpnt20
chkpnt30
['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'abc',
 'efg']
['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'abc',
 'efg',
 'hij']

The output is in the order of chkpnt10, chkpnt20, chkpnt30 (the code is running). The class object contains abc and efg, but not hij. The instance object contains all abc, evg, and hij. The first argument of \ __ new__ is a class object, and in the above code, efg is set, so efg is added to the class object as a result. With super (sampleCls, cls) .__ new __ (cls), an instance object is created from the class object and returned as a return value. The return value of \ __ new__ should be an instance object of that class. If the return value is other than that, the instance object will not be created by the class object. init is called with the instance object created by \ __ new__ as the first argument. So \ new is for creating an instance object from a class object. As in the code above, overriding \ __ new__ allows you to change the class object from which the instance object is created, and this change will be reflected in the generated instance object as well. From the above, I thought that \ __ new__ was not a constructor.

By the way, in the class, ・ Type (new style class) and ・ Class object (old style class) The above sample is a new style class. It seems.

Since I am using python which is installed by default when DataNitro is installed, the above is the one executed in 2.7. In 2.7, in order to call (overridden?) New, you need to inherit object or something. [* 2](# 2) </ sub> [* 3](# 3) </ sub> (Since 3.0 or later, object is inherited by default, so it is no longer necessary to specify inheriting the class.)

I've been researching python for the past few days, and there is a mechanism that allows me to control it fairly finely with a program, so even if I focus on the class, I still feel that something is hazy. You can check one after another ... But I don't hate it. If you do it, you may be addicted to it in a good way.

As an aside, since 3.0, there have been changes that affect the implementation level, such as changing from sentences to expressions and having to put parentheses. It seems that the interface of the library has also changed.

I wonder if I will continue studying python for a while.


* 1. Perhaps some books have init as a constructor. Rather more? * 2. I'm trying to find out the causal relationship between inheriting an object and calling \ __ new__, and I wonder if the attribute value controls the call to \ __ new__. I looked it up, but I couldn't find it. Even if * 3. type is inherited, \ __ new__ is called. However, in this case, the meaning may be slightly different due to the relationship with the metaclass. Future research issues on type.

Recommended Posts

I did a little research on the class
I did a lot of research on how Python is executed
A note on customizing the dict list class
What I did when I stumbled on a Django tutorial
I just changed the sample source of Python a little.
I made a VGG16 model using TensorFlow (on the way)
I tried a little bit of the behavior of the zip function
On Linux, the time stamp of a file is a little past.
I relaxed the conditions a little and let optuna solve Sudoku
After researching the Python library, I understood a little about egg.info.
A class that hits the DMM API
I stumbled on the Hatena Keyword API
I made a kitchen timer to be displayed on the status bar!
I installed Kivy on a Mac environment
I measured the run queue wait time of a process on Linux
What I did with a Python array
A little more detail on python comprehensions
[Python, ObsPy] I drew a beach ball on the map with Cartopy + ObsPy.
I built a TensorFlow environment on windows10
[Python] A progress bar on the terminal
I gave a poster presentation at the 36th Joint Conference on Medical Informatics.
I made a program to look up words on the window (previous development)
I didn't have to write a decorator in the class Thank you contextmanager
I wrote a class in Python3 and Java
Python: Prepare a serializer for the class instance:
I ran the neural network on the actual FPGA
A note about the new style base class
[PyTorch] I was a little lost in torch.max ()
Create a Python execution environment on IBM i
As a beginner, I searched the / proc directory
I tried playing with the calculator on tkinter
I use python but I don't know the class well, so I will do a tutorial
[Example of Python improvement] I learned the basics of Python on a free site in 2 weeks.
The world changed when I opened a big Python project (Django) on Sourcetrail (Linux)
The concept of reference in Python collapsed for a moment, so I experimented a little.
It was a life I wanted to OCR on AWS Lambda to locate the characters.
I want to take a screenshot of the site on Docker using any font
A little addictive information about Cliff, the CLI framework
Draw a graph in Julia ... I tried a little analysis
I tried Python on Mac for the first time.
Specify the volume on linux and make a sound
I tried running the app on the IoT platform "Rimotte"
A brief note on the anger caused by scraping
Create a QR code for the URL on Linux
Maybe I overestimated the impact of ShellShock on CGI
I tried python on heroku for the first time
A python implementation of the Bayesian linear regression class
I want to find a popular package on PyPi
I got a UnicodeDecodeError when pip install on ubuntu
Make a breakpoint on the c layer with python
I made a Python3 environment on Ubuntu with direnv.
I tried a visual regression test on GitHub Pages
Write a log-scale histogram on the x-axis in python
I want a Spotify sleep timer on my PC
A memo that I touched the Datastore with python
I made a command to markdown the table clipboard
What I did to ssh to the VPS Ubuntu environment
A Study on Visualization of the Scope of Prediction Models
I tried Kaokore, a Japanese classic dataset, on EfficientNet.
I tried installing the Linux kernel on virtualbox + vagrant
I tried to notify the honeypot report on LINE