Você está na página 1de 15

How to Write Functions in Python

Hayao Suzuki

PyCon JP Reject Conference 2017 at TECH PLAY SHIBUYA

September 6, 2017
Who Am I?

About Me
Name Hayao Suzuki (@CardinalXaro)
Blog http://xaro.hatenablog.jp/
Major Mathematics (Combinatorics, Number Theory)
Work Python Programmer at iRidge, Inc.

Reviewed Books
Effective Python (O’Reilly Japan)
アルゴリズムクイックリファレンス 第 2 版 (O’Reilly Japan)
初めての PHP (O’Reilly Japan)
Effective Debugging (O’Reilly Japan)
すらすらわかる Python (翔泳社)
Python と JavaScript ではじめるデータビジュアライゼーション
(O’Reilly Japan)

2 / 15
Today’s Theme

How to Write Functions in Python


Surface-Level Improvements
The Power of Keyword Arguments
Stateful Functions

3 / 15
Surface-Level Improvements

I’ve bought this book twice.

4 / 15
Surface-Level Improvements

Ugly Example
def f(ns):
sum=0
for i in ns:
sum=sum+i
return sum

print(f([1,2,3,4,5]))

5 / 15
Surface-Level Improvements

Improvement Point
Follow the PEP 8.

Follow the PEP 8 Example


def f(ns):
sum = 0
for i in ns:
sum = sum + i
return sum

print(f([1, 2, 3, 4, 5]))

6 / 15
Surface-Level Improvements

Improvement Point
Consider namespace (e.g. sum is a builtin-function).

sum ! total
def f(ns):
total = 0
for i in ns:
total = total + i
return total

print(f([1, 2, 3, 4, 5]))

7 / 15
Surface-Level Improvements

Improvement Point
Packing Iinformation into names.

Improve names
def summation(numbers):
total = 0
for number in numbers:
total = total + number
return total

print(summation([1, 2, 3, 4, 5]))

8 / 15
Surface-Level Improvements

Improvement Point
Docstring, Type hints.

Readble Example
from typing import List

def summation(numbers: List) -> int:


"""Calculate summation of numbers"""
total = 0
for number in numbers:
total = total + number
return total

print(summation([1, 2, 3, 4, 5]))

9 / 15
The Power of Keyword Arguments

Keyword Args with Default Value


Add new behaivors to a function.

Default Value
from typing import List

def summation(numbers: List, modulo: int = 1) -> int:


"""Calculate summation of numbers"""
total = 0
for number in numbers:
total = total + number
return total % modulo

print(summation([1, 2, 3, 4, 5])) # No Change!


print(summation([1, 2, 3, 4, 5], modulo=4)) # 15 % 5 = 3

10 / 15
The Power of Keyword Arguments

Keyword Only Args (Python 3 Only)


Force callers to supply keyword args.

Keyword Only Args


from typing import List

def summation(numbers: List, *, modulo: int = 1) -> int:


"""Calculate summation of numbers"""
total = 0
for number in numbers:
total = total + number
return total % modulo

print(summation([1, 2, 3, 4, 5], modulo=5)) # 0


print(summation([1, 2, 3, 4, 5], 5)) # raise TypeError

11 / 15
The Power of Keyword Arguments

Mutable Default Value


Default value is only executed a single time when the function is
defined.

The Same Timestamp


>>> from datetime import datetime
>>> from time import sleep
>>> def log(message, when=datetime.now()):
... print(f"{message}: {when}")
...
>>> log("Good Morning!")
Good Morning!: 2017-09-03 22:20:40.786377
>>> sleep(1.0)
>>> log("おはようございます")
おはようございます: 2017-09-03 22:20:40.786377

12 / 15
The Power of Keyword Arguments

Mutable Default Value


Use None to Mutable Default Value.

The Correct Timestamp


>>> from datetime import datetime
>>> from time import sleep
>>> def log(message, when=None):
... when = datetime.now() if when is None else when
... print(f"{message}: {when}")
...
>>> log("Good Morning!")
Good Morning!: 2017-09-03 22:20:41.786424
>>> sleep(1.0)
>>> log("おはようございます")
おはようございます: 2017-09-03 22:20:42.787629

13 / 15
Stateful Functions
Stateful Function
Implement callable class.

Implements Summation with Histories


class Summation:
def __init__(self):
self.histories = list()

def __call__(self, numbers, *, modulo=1):


total = sum(numbers) % modulo
self.histories.append((numbers, modulo, total))
return total

summation = Summation()
print(summation([1, 2, 3, 4, 5]))
print(summation([1, 2, 3], modulo=3))
print(summation.histories)

14 / 15
Summary

Summary
If you don’t have "The Art of Readable Code", go to a
bookstore and buy it.
Follow the PEP 8. Consider built-in namespaces.
Keyword Arguments are very powerful. Be careful of mutable
default values.
If you want to implement stateful functions, we recommend
callable class instead of closures.

References
リーダブルコード (O’Reilly Japan)
Effective Python (Addison-Wesley)

15 / 15