Slide 1

Slide 1 text

Effective Python in Python 3.6 Hayao Suzuki Python 3.6 Release Party at Yahoo Japan January 31, 2017

Slide 2

Slide 2 text

Who Are You? About Me Name Hayao Suzuki (@CardinalXaro) Blog http://xaro.hatenablog.jp/ Major Mathematics (Combinatorics, Number Theory) Work Python Programmer (Not Mathematics!) Reviewed Books Effective Python (O’Reilly Japan) Algorithms in A Nutshell 2nd ed. (O’Reilly Japan) And more...? 2 / 9

Slide 3

Slide 3 text

Today’s Theme Metaprogramming without Metaclasses Metaclass can create extremely bizarre behaviors that are unapproachable to newcomers. (Effective Python, P.87) 3 / 9

Slide 4

Slide 4 text

Metaprogramming without Metaclasses Items about Metaclass in Effective Python Item 33 Validate Subclasses with Metaclasses Item 34 Register Class Existence with Metaclasses Item 35 Annotate Class Attributes with Metaclasses Using Python 3.6, we can write metaprogramming without using metaclass. 4 / 9

Slide 5

Slide 5 text

Item 33 With Metaclasses class ValidatePolygon(type): def __new__(meta, name, bases, class_dict): if bases != (object,): if class_dict["sides"] < 3: raise ValueError("polygons need 3+ sides.") return type.__new__(meta, name, bases, class_dict) class Polygon(object, metaclass=ValidatePolygon): sides = None @classmethod def interior_angles(cls): return (cls.sides - 2) * 180 class Triangle(Polygon): sides = 3 5 / 9

Slide 6

Slide 6 text

Item 33 Without Metaclasses class Polygon(object): def __init_subclass__(cls, sides, **kwargs): cls.sides = sides if cls.sides < 3: raise ValueError("polygons need 3+ sides.") @classmethod def interior_angles(cls): return (cls.sides - 2) * 180 class Triangle(Polygon, sides=3): pass 6 / 9

Slide 7

Slide 7 text

Item 35 with Metaclasses class Meta(type): def __new__(meta, name, bases, class_dict): for key, value in class_dict.items(): if isinstance(value, Field): value.name = key value.internal_name = '_' + key return type.__new__(meta, name, bases, class_dict) class Field(object): def __init__(self): self.name = None self.internal_name = None def __get__(self, instance, instance_type): if instance is None: return self return getattr(instance, self.internal_name, '') def __set__(self, instance, value): setattr(instance, self.internal_name, value) class DatabaseRow(object, metaclass=Meta): pass class Customer(DatabaseRow): first_name = Field() 7 / 9

Slide 8

Slide 8 text

Item 35 Without Metaclasses class Field(object): def __init__(self): self.name = None self.internal_name = None def __get__(self, instance, instance_type): if instance is None: return self return getattr(instance, self.internal_name, '') def __set__(self, instance, value): setattr(instance, self.internal_name, value) def __set_name__(self, owner, name): self.name = name self.internal_name = '_' + name class Customer(object): first_name = Field() 8 / 9

Slide 9

Slide 9 text

Summary Summary Using Python 3.6, we can write metaprogramming without using metaclass. Item 33 to Item 35 in Effective Python no longer have to use metaclass. Python 3.6 is good I think. 9 / 9