Friday I / O. At Wamuu Co., Ltd., every Friday is a day when we work on what we are interested in and output the results in some way. Everyone should do what they like on Friday!
People who are "getting used to Python" will learn more and more new things. I think there are still many things we don't know about in the Python world. (Full of things I don't even know)
You know the list comprehension, but you can actually write other than the list! !!
#Dictionary comprehension
print({v: v * 10 for v in range(0, 10)})
#set comprehension
l = [1, 1, 1, 2, 2, 2, 3, 3, 3]
print({v * 10 for v in l})
No! I'll write the tuple inclusion notation! Even if I say
and write the following, it doesn't work! !! !!
print((v * 10 for v in range(0, 10)))
In this case, generator object
is returned.
That means you can do the following.
print(tuple(v * 10 for v in range(0, 10)))
Have you ever used with
in a file open sample?
That's it.
with open(filepath) as f:
content = f.read(-1)
When you exit the with statement, the file is automatically closed, but that uses a mechanism called a context manager.
class ContextManager(object):
def __enter__(self):
print('Yes! !! !!')
return 'rice ball'
def __exit__(self, exc_type, exc_value, traceback):
print('Deta! !! !!')
with ContextManager() as value: # value == 'rice ball'
print(value)
When entering the with statement, __enter__
is called, and when exiting, __exit__
is called.
Very simple.
In Python, you can create a class that behaves specially only if it belongs to a certain class.
class Person(object):
def __init__(self, last_name, first_name):
self.last_name = last_name
self.first_name = first_name
self.parent = None
#This is Kimo!
def __get__(self, parent, klass):
self.parent = parent
return self
@property
def fullname(self):
if self.parent:
return self.parent.last_name + self.first_name
return self.last_name + self.first_name
A normal class when instantiated and used normally.
gakky = Person('Arakaki', 'Yui')
print(gakky.fullname) #Aragaki Yui
However, if you belong to a certain class, the behavior will change!
class Man(Person):
#Everyone's wife!
yome = Person('Arakaki', 'Yui')
#At this time, everyone's wife is still there.
print(Man.yome.fullname) #Aragaki Yui
#I!
ore = Man('Yamada', 'Taro')
#Kecorn! !! !! !!
print(ore.yome.fullname) #Yui Yamada! !! !! !! !!
For references via classes or instances, __get__
is executed.
It is very convenient when creating a class that refers to the value of the class to which it belongs.
It's implemented as Django Utilities, but the @property
decorator cache feature Ancillary guy.
If you call it once, the result will be cached, so if you do heavy processing internally, you can become a PC-friendly person.
class cached_property(object):
def __init__(self, func):
self.__doc__ = getattr(func, '__doc__')
self.func = func
def __get__(self, parent, klass):
if parent is None:
return self
value = parent.__dict__[self.func.__name__] = self.func(parent)
return value
class Hoge(object):
@cached_property
def value(self):
import time
time.sleep(10)
return 'It was a heavy process'
hoge = Hoge()
print(hoge.value)
print(hoge.value)
This is the correct way to use descriptors! !! !! There is also a single library.
This is Python's black magic
.
It is a mechanism that can dynamically change the definition of the class, but if you implement it as follows, you can become a big liar.
class MetaClass(type):
def __new__(klass, name, bases, attrs):
"""
arguments:
klass --MetaClass itself
bases --Hoge's name
bases --Hoge's parent classes
attrs --Hoge's class variables and functions
return:
Class to actually use
"""
# new_Hoge is in class
new_class = super(MetaClass, klass).__new__(klass, name, bases, attrs)
#I'll return an int!
return int
#Inherit list! !!
class Hoge(list, metaclass=MetaClass):
pass
#Ignore cancer! !! !!
print(Hoge) # <class 'int'>
Aside from this kind of material implementation, Metaclass is a technology that most of the complicated libraries use, so I think it will be a learning experience to see this and that. It's a planned use because it behaves ignoring various things, but the implementation is neat, so please try it.
class MetaClass(type):
def __new__(klass, name, bases, attrs):
new_class = super(MetaClass, klass).__new__(klass, name, bases, attrs)
silent = attrs.get('silent', False)
if silent:
new_class.say = lambda s: print('。。。')
return new_class
class Person(object):
def say(self):
print('Hello Hello Hello Hello! !! !!')
class Ore(Person, metaclass=MetaClass):
silent = False
class Omae(Person, metaclass=MetaClass):
silent = True
Ore().say() #Hello Hello Hello Hello! !! !!
Omae().say() # 。。。
If you want to remove an empty element from the array, you can write it like this:
def ignore_empty(l):
return list(filter(None, l))
print(ignore_empty([1, None, 0, 2, '', 3]))
https://docs.python.jp/3/library/functions.html#filter
flatten
Sometimes you want to make a multidimensional array one-dimensional! In the case of a two-dimensional array, you can write it exactly.
from itertools import chain
def flatten(l):
return list(chain.from_iterable(l))
print(flatten([
[1,2,3],
[4,5,6],
[7,8,9],
]))
It seems that you have to implement it properly if it is more multidimensional or mixed.
Summary of how to flatten a list in Python
If you write a conditional expression that the file name matches hoge.txt or piyo.md
, it will be as follows.
if filename in ['hoge.txt', 'piyo.md']:
pass
Then I wanted to add hige.text
and ʻiiyo.md` to this, and then I had to write a very long array like that.
if filename in ['hoge.txt', 'hige.text', 'piyo.md', 'iiyo.md', ...]:
pass
The following functions are useful in such cases.
You can write flexibly like a Unix glob
.
from fnmatch import fnmatch
class glob_list(list):
def __contains__(self, value):
for pattern in self:
if fnmatch(value, pattern):
return True
return False
l = glob_list(['??ge.txt', '?iyo.md'])
assert 'hoge.txt' in l
assert 'hige.txt' in l
assert 'piyo.md' in l
assert 'iiyo.md' in l
Python is really useful. We hope that you can contribute to improving your skills as much as possible.
Recommended Posts