SlideShare a Scribd company logo
1 of 139
class Base:
pass
class Sub(Base):
pass
Subclassing
class Base:
pass
class Sub(Base):
pass
Subclassing
@dataclass
class Base:
x: int
class Sub(Base):
y = 0
def compute(self):
self.y += self.x * 2
@dataclass
class Base:
x: int
def cool_new_feature(self):
self.y = "LOL"
class Sub(Base):
y = 0
def compute(self):
self.y += self.x * 2
Composition
@dataclass
class A
b: B
y: int = 0
Composition
@dataclass
class A
b: B
y: int = 0
Composition
@dataclass
class A
b: B
y: int = 0
def compute(self):
self.y += self.b.x * 2
Composition
@dataclass
class A
b: B
y: int = 0
def compute(self):
self.y += self.b.x * 2
Composition
Goose Chase
Program Flow™
class A:
def method(self): ...
class B:
def method(self): ...
class C:
def method(self): ...
class You(A, B, C):
def foo(self):
self.method()
class A:
def method(self):
self.bar()
class B(A):
def bar(self): ...
class C(B):
def bar(self): ...
class You(C):
def foo(self):
self.method()
class A:
def method(self):
self.bar()
class B(A):
def bar(self): ..
class C(B):
def bar(self): ..
.
.
class You(C):
def foo(self):
self.method()
— Architecture Patterns with Python, page 131
— Architecture Patterns with Python, page 131
Repository
Tracking
Repository
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
@abc.abstractmethod
def _add(self, product):
raise NotImplementedError
@abc.abstractmethod
def _get(self, sku):
raise NotImplementedError
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
def add_product(self, product):
self._add(product)
self.seen.add(product)
@abc.abstractmethod
def _add(self, product):
raise NotImplementedError
@abc.abstractmethod
def _get(self, sku):
raise NotImplementedError
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
def add_product(self, product):
self._add(product)
self.seen.add(product)
def get_by_sku(self, sku):
if product := self._get(sku):
self.seen.add(product)
return product
@abc.abstractmethod
def _add(self, product):
raise NotImplementedError
@abc.abstractmethod
def _get(self, sku):
raise NotImplementedError
class FakeTrackingRepository(AbstractTrackingRepository):
def init (self, products):
super(). init ()
self._products = set(products)
class FakeTrackingRepository(AbstractTrackingRepository):
def init (self, products):
super(). init ()
self._products = set(products)
def _add(self, product):
self._products.add(product)
def _get(self, sku):
return next((
p for p in self._products
if p.sku == sku),
None)
class FakeTrackingRepository(AbstractTrackingRepository):
def init (self, products):
super(). init ()
self._products = set(products)
def _add(self, product):
self._products.add(product)
def _get(self, sku):
return next((
p for p in self._products
if p.sku == sku),
None)
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
def add_product(self, product):
self._add(product)
self.seen.add(product)
def get_by_sku(self, sku):
if product := self._get(sku):
self.seen.add(product)
return product
@abc.abstractmethod
def _add(self, product):
raise NotImplementedError
@abc.abstractmethod
def _get(self, sku):
raise NotImplementedError
class AbstractTrackingRepository(abc.ABC):
def init (self):
self.seen = set()
def add_product(self, product):
self._add(product)
self.seen.add(product)
def get_by_sku(self, sku):
if product := self._get(sku):
self.seen.add(product)
return product
@abc.abstractmethod
def _add(self, product):
raise NotImplementedError
@abc.abstractmethod
def _get(self, sku):
raise NotImplementedError
class AbstractRepository(abc.ABC):
@abc.abstractmethod
def add(self, product: Product) -> None:
...
@abc.abstractmethod
def get(self, sku: str) -> Product | None:
...
class AbstractRepository(abc.ABC):
@abc.abstractmethod
def add(self, product: Product) -> None:
...
@abc.abstractmethod
def get(self, sku: str) -> Product | None:
...
Nominal subtyping
y(abc.ABC):
Nominal subtyping
class AbstractRepositor (metaclass=abc.ABCMeta):
@abc.abstractmethod
def add(self, product: Product) -> None:
...
@abc.abstractmethod
def get(self, sku: str) -> Product | None:
...
@typing.runtime_checkable
class Repository(typing.Protocol):
def add(self, product: Product) -> None:
...
def get(self, sku: str) -> Product | None:
...
@typing.runtime_checkable
class Repository(typing.Protocol):
def add(self, product: Product) -> None:
...
def get(self, sku: str) -> Product | None:
...
@typing.runtime_checkable
class Repository(typing.Protocol):
def add(self, product: Product) -> None:
...
def get(self, sku: str) -> Product | None:
...
Structural subtyping
class FakeRepository:
def init (self, products):
self._products = set(products)
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
def get(self, sku: str) -> Product | None:
return next((
p for p
in self._products
if p.sku == sku),
None)
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
def get(self, sku: str) -> Product | None:
return next((
p for p
in self._products
if p.sku == sku),
None)
class FakeRepository(AbstractRepository):
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
def get(self, sku: str) -> Product | None:
return next((
p for p
in self._products
if p.sku == sku),
None)
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
def get(self, sku: str) -> Product | None:
return next((
p for p
in self._products
if p.sku == sku),
None)
AbstractRepository.register(FakeRepository)
@AbstractRepository.register
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product: Product ) -> None:
self._products.add(product)
def get(self, sku: str) -> Product | None:
return next((
p for p
in self._products
if p.sku == sku),
None)
@dataclass
class TrackingRepository:
_repo: Repository
seen: set[Product] = field(default_factory=set)
@dataclass
class TrackingRepository:
_repo: Repository
seen: set[Product] = field(default_factory=set)
def add_product(self, product: Product) -> None:
self._repo.add(product)
self.seen.add(product)
@dataclass
class TrackingRepository:
_repo: Repository
seen: set[Product] = field(default_factory=set)
def add_product(self, product: Product) -> None:
self._repo.add(product)
self.seen.add(product)
def get_by_sku(self, sku: str) -> Product | None:
if product := self._repo.get(sku):
self.seen.add(product)
return product
@dataclass
class TrackingRepository:
_repo: Repository
seen: set[Product] = field(default_factory=set)
def add_product(self, product):
self._repo.add(product)
self.seen.add(product)
def get_by_sku(self, sku):
if product := self._repo.get(sku):
self.seen.add(product)
return product
class FakeRepository:
def init (self, products):
self._products = set(products)
def add(self, product):
self._products.add(product)
def get(self, sku):
return next(
(
p for p
in self._products
if p.sku == sku
),
None
)
Subclassing
requires knowledge + self-discipline
Subclassing
requires knowledge + self-discipline
Composition
mechanically enforces discipline
Namespaces are one honking great
idea – let’s do more of those!
— Uncle Timmy, Zen of Python, PEP 20
def decorator(cls):
cls.a = 42
return cls
def decorator(cls):
cls.a = 42
return cls
@decorator
class C
pass
def decorator(cls):
cls.a = 42
return cls
@decorator
class C
pass
assert hasattr(C, "a")
def decorator(cls):
cls.a = 42
return cls
@decorator
class C
pass
assert hasattr(C, "a")
== C = decorator(_C)
class Question(django.db.models.Model):
question_text = CharField(max_length=200)
pub_date = DateTimeField('date published')
class Question(django.db.models.Model):
question_text = CharField(max_length=200)
pub_date = DateTimeField('date published')
@dataclass
@attrs.define
class Question:
question_text: str
pub_date: datetime
class Question(django.db.models.Model):
question_text = CharField(max_length=200)
pub_date = DateTimeField('date published')
@dataclass
class Question:
question_text: str
pub_date: datetime
[' annotations ', ' class ', ' dataclass_fields ', ' dataclass_params ',
' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ',
' getattribute ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ',
' lt ', ' match_args ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ',
' repr ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ',
'pub_date', 'question_text']
dir(Question("Hi!", today())) – dataclass Edition
[' annotations ', ' class ', ' dataclass_fields ', ' dataclass_params ',
' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ',
' getattribute ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ',
' lt ', ' match_args ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ',
' repr ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ',
'pub_date', 'question_text']
dir(Question("Hi!", today())) – dataclass Edition
['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ',
' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getstate ',
' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' module ',
' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ',
' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ',
'_check_column_name_clashes', '_check_constraints', '_check_default_pk',
'_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together',
'_check_indexes', '_check_local_fields', '_check_long_column_names',
'_check_m2m_through_same_relationship', '_check_managers', '_check_model',
'_check_model_name_db_lookup_clashes', '_check_ordering',
'_check_property_name_related_field_accessor_clashes', '_check_single_primary_key',
'_check_swappable', '_check_unique_together', '_do_insert', '_do_update',
'_get_FIELD_display', '_get_expr_references', '_get_field_value_map',
'_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val',
'_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks',
'_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state',
'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db',
'full_clean', 'get_constraints', 'get_deferred_fields', 'get_next_by_pub_date',
'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'pub_date',
'question_text', 'refresh_from_db', 'save', 'save_base', 'serializable_value',
'unique_error_message', 'validate_constraints', 'validate_unique']
dir(Question("Hi!", today())) – ORM Edition
['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ',
' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getstate ',
' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' module ',
' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ',
' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ',
'_check_column_name_clashes', '_check_constraints', '_check_default_pk',
'_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together',
'_check_indexes', '_check_local_fields', '_check_long_column_names',
'_check_m2m_through_same_relationship', '_check_managers', '_check_model',
'_check_model_name_db_lookup_clashes', '_check_ordering',
'_check_property_name_related_field_accessor_clashes', '_check_single_primary_key',
'_check_swappable', '_check_unique_together', '_do_insert', '_do_update',
'_get_FIELD_display', '_get_expr_references', '_get_field_value_map',
'_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val',
'_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks',
'_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state',
'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db',
'full_clean', 'get_constraints', 'get_deferred_fields', 'get_next_by_pub_date',
'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'pub_date',
'question_text', 'refresh_from_db', 'save', 'save_base', 'serializable_value',
'unique_error_message', 'validate_constraints', 'validate_unique']
dir(Question("Hi!", today())) – ORM Edition
class QuestionsRepository:
conn: sqlalchemy.engine.Connection
def get(self, id: int) -> Question:
row = conn.execute(
self.
select(
tables.questions.c.pub_date
).where(
tables.questions.c.id == id
)
).one()
return Question(id=id, pub_date=row.pub_date)
-> Question
class QuestionsRepository:
conn: sqlalchemy.engine.Connection
def get(self, id: int) :
row = self.conn.execute(
select(
tables.questions.c.pub_date
).where(
tables.questions.c.id == id
)
).one()
return Question(id=id, pub_date=row.pub_date)
class QuestionsRepository:
conn: sqlalchemy.engine.Connection
def get(self, id: int) -> Question:
row = self.conn.execute(
select(
tables.questions.c.pub_date
).where(
tables.questions.c.id == id
)
).one()
return Question(id=id, pub_date=row.pub_date)
['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ',
getstate ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ',
lt ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ',
setattr ', ' setstate ', ' sizeof ', ' str ', ' subclasshook ',
' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ',
'
'
'
' weakref ', '_check_column_name_clashes', '_check_constraints', '_check_default_pk',
'_check_field_name_clashes', '_check_fields', '_check_id_field',
'_check_index_together', '_check_indexes', '_check_local_fields',
'_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers',
'_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering',
'_check_property_name_related_field_accessor_clashes', '_check_single_primary_key',
'_check_swappable', '_check_unique_together', '_do_insert', '_do_update',
'_get_FIELD_display', '_get_expr_references', '_get_field_value_map',
'_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val',
'_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks',
'_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val',
'_state', 'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message',
'delete', 'from_db', 'full_clean', 'get_constraints', 'get_deferred_fields',
'get_next_by_pub_date', 'get_previous_by_pub_date', 'id', 'objects', 'pk',
'prepare_database_save', 'pub_date', 'question_text', 'refresh_from_db', 'save',
'save_base', 'serializable_value', 'unique_error_message', 'validate_constraints',
'validate_unique']
Readability
Readability
Control
Readability Convenience
Control
Readability Convenience
Control Performance
Seth Michael Larson
Working on urllib3 full-time for one week
Programs are meant to
be read by humans and
only incidentally for
computers to execute.
— Abelson & Sussman, SICP
Seth Michael Larson
Working on urllib3 full-time for one week
class A:
b: B
def other_method(): ...
def method(self):
self.other_method()
self.b.even_other_method()
class B:
a: A
def even_other_method(): ...
def method(self):
self.a.other_method()
self.even_other_method()
or
class A:
b: B
def other_method(): ...
def method(self):
self.other_method()
self.b.even_other_method()
class B:
a: A
def even_other_method(): ...
def method(self):
self.a.other_method()
self.even_other_method()
or
def function(a, b):
a.other_method()
b.even_other_method()
class C:
a: A
b: B
def method(self):
self.a.other_method()
self.b.even_other_method()
Exceptions
class MyError(Exception):
pass
Exceptions
class MyError(Exception):
pass
class MyError(ValueError, KeyError):
pass
Exceptions
class MyError(Exception):
pass
class MyError(ValueError, KeyError):
pass
Exceptions
E-Mail Addresses
class Mailbox:
id: UUID
addr: str
pwd: str
E-Mail Addresses
class Mailbox:
id: UUID
addr: str
pwd: str
class Forwarder
id: UUID
addr: str
targets: list[str]
E-Mail Addresses
class Mailbox:
id: UUID
addr: str
pwd: str
class Forwarder
id: UUID
addr: str
targets: list[str]
E-Mail Addresses
EmailAddr = Forwarder | Mailbox
class Mailbox:
id: UUID
addr: str
pwd: str
class Forwarder
id: UUID
addr: str
targets: list[str]
E-Mail Addresses
EmailAddr = Forwarder | Mailbox
Duplication is far cheaper
than a wrong abstraction.
— Sandi Metz
Create one class, make fields optional
class AddrType(enum.Enum):
MAILBOX = "mailbox"
FORWARDER = "forwarder"
class EmailAddr
type: AddrType
id: UUID
addr: str
Create one class, make fields optional
class AddrType(enum.Enum):
MAILBOX = "mailbox"
FORWARDER = "forwarder"
class EmailAddr
type: AddrType
id: UUID
addr: str
# Only useful if type == AddrType.MAILBOX
pwd: str | None
# Only useful if type == AddrType.FORWARDER
target: list[str] | None
Create one class, make fields optional
class AddrType(enum.Enum):
MAILBOX = "mailbox"
FORWARDER = "forwarder"
class EmailAddr
type: AddrType
id: UUID
addr: str
# Only useful if type == AddrType.MAILBOX
pwd: str | None
# Only useful if type == AddrType.FORWARDER
target: list[str] | None
Create one class, make fields optional
Composition
class EmailAddr:
id: UUID
addr: str
Composition
class EmailAddr:
id: UUID
addr: str
class Mailbox
email: EmailAddr
pwd: str
Composition
class EmailAddr:
id: UUID
addr: str
class Mailbox
email: EmailAddr
pwd: str
class Forwarder
email: EmailAddr
targets: list[str]
Composition
class EmailAddr:
id: UUID
addr: str
class Mailbox
email: EmailAddr
pwd: str
class Forwarder
email: EmailAddr
targets: list[str]
Composition
class EmailAddr:
id: UUID
addr: str
class Mailbox
email: EmailAddr
pwd: str
class Forwarder
email: EmailAddr
targets: list[str]
Composition
Create a Common Base Class, Then Specialize
class EmailAddr:
id: UUID
addr: str
Create a Common Base Class, Then Specialize
class EmailAddr:
id: UUID
addr: str
class Mailbox(EmailAddr):
pwd: str
class Forwarder(EmailAddr):
targets: list[str]
Create a Common Base Class, Then Specialize
class EmailAddr:
id: UUID
addr: str
class Mailbox(EmailAddr):
pwd: str
class Forwarder(EmailAddr):
targets: list[str]
Create a Common Base Class, Then Specialize
type EmailAddr struct {
addr string
}
type Mailbox struct {
EmailAddr
pwd string
}
type EmailAddr struct {
addr string
}
type Mailbox struct {
EmailAddr
pwd string
}
func main() {
mbox := Mailbox{EmailAddr{"addr@example.com"},
"a hash"}
fmt.Println(mbox.addr)
}
type EmailAddr struct {
addr string
}
type Mailbox struct {
EmailAddr
pwd string
}
func main() {
mbox := Mailbox{EmailAddr{"addr@example.com"},
"a hash"}
fmt.Println(mbox.addr)
}
I never allow myself to have an
opinion on anything that I don’t
know the other side’s argument
better than they do.
— Charlie Munger
OX.CX/SC
OX.CX/SC
@HYNEK
(@MASTODON.SOCIAL)
OX.CX/SC
@HYNEK
(@MASTODON.SOCIAL)
YOUTUBE.COM/
@THE_HYNEK

More Related Content

Similar to "Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack

PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAMaulik Borsaniya
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved againrik0
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲Mohammad Reza Kamalifard
 
Declarative Data Modeling in Python
Declarative Data Modeling in PythonDeclarative Data Modeling in Python
Declarative Data Modeling in PythonJoshua Forman
 
Practical Google App Engine Applications In Py
Practical Google App Engine Applications In PyPractical Google App Engine Applications In Py
Practical Google App Engine Applications In PyEric ShangKuan
 
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونیاسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونیMohammad Reza Kamalifard
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con djangoTomás Henríquez
 
Py.test
Py.testPy.test
Py.testsoasme
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonChristoph Matthies
 
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnGoptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnMasashi Shibata
 
Machine Learning Algorithms
Machine Learning AlgorithmsMachine Learning Algorithms
Machine Learning AlgorithmsHichem Felouat
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
Odoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new apiOdoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new apiOdoo
 
Object_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdfObject_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdfKoteswari Kasireddy
 
Python Metaprogramming
Python MetaprogrammingPython Metaprogramming
Python MetaprogrammingSDU CYBERLAB
 

Similar to "Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack (20)

PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
 
Declarative Data Modeling in Python
Declarative Data Modeling in PythonDeclarative Data Modeling in Python
Declarative Data Modeling in Python
 
Practical Google App Engine Applications In Py
Practical Google App Engine Applications In PyPractical Google App Engine Applications In Py
Practical Google App Engine Applications In Py
 
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونیاسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con django
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Python classes objects
Python classes objectsPython classes objects
Python classes objects
 
Py.test
Py.testPy.test
Py.test
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in Python
 
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnGoptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Machine Learning Algorithms
Machine Learning AlgorithmsMachine Learning Algorithms
Machine Learning Algorithms
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
Odoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 APIOdoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 API
 
Odoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new apiOdoo - From v7 to v8: the new api
Odoo - From v7 to v8: the new api
 
Object_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdfObject_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdf
 
Python Metaprogramming
Python MetaprogrammingPython Metaprogramming
Python Metaprogramming
 

More from Fwdays

"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y..."How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...Fwdays
 
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil TopchiiFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro SpodaretsFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi
"Distributed graphs and microservices in Prom.ua",  Maksym Kindritskyi"Distributed graphs and microservices in Prom.ua",  Maksym Kindritskyi
"Distributed graphs and microservices in Prom.ua", Maksym KindritskyiFwdays
 
"Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl..."Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl...Fwdays
 
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T..."How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...Fwdays
 
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ..."The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...Fwdays
 
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu..."[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...Fwdays
 
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care..."[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...Fwdays
 
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"..."4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...Fwdays
 
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast..."Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...Fwdays
 
"Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others..."Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others...Fwdays
 
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?", Oleksandra MyronovaFwdays
 
"Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv..."Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv...Fwdays
 
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin..."How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...Fwdays
 
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy TytenkoFwdays
 

More from Fwdays (20)

"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y..."How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
 
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi
"Distributed graphs and microservices in Prom.ua",  Maksym Kindritskyi"Distributed graphs and microservices in Prom.ua",  Maksym Kindritskyi
"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi
 
"Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl..."Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl...
 
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T..."How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
 
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ..."The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
 
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu..."[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
 
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care..."[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
 
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"..."4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
 
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast..."Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
 
"Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others..."Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others...
 
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
 
"Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv..."Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv...
 
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin..."How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
 
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
 

Recently uploaded

AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024Stephen Perrenod
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...FIDO Alliance
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeCzechDreamin
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101vincent683379
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?Mark Billinghurst
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityScyllaDB
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FIDO Alliance
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfFIDO Alliance
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastUXDXConf
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfFIDO Alliance
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...FIDO Alliance
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceSamy Fodil
 
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPTiSEO AI
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIES VE
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...CzechDreamin
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaCzechDreamin
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfFIDO Alliance
 

Recently uploaded (20)

AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack

  • 1.
  • 2.
  • 3.
  • 4.
  • 7. @dataclass class Base: x: int class Sub(Base): y = 0 def compute(self): self.y += self.x * 2
  • 8. @dataclass class Base: x: int def cool_new_feature(self): self.y = "LOL" class Sub(Base): y = 0 def compute(self): self.y += self.x * 2
  • 9.
  • 11. @dataclass class A b: B y: int = 0 Composition
  • 12. @dataclass class A b: B y: int = 0 Composition
  • 13. @dataclass class A b: B y: int = 0 def compute(self): self.y += self.b.x * 2 Composition
  • 14. @dataclass class A b: B y: int = 0 def compute(self): self.y += self.b.x * 2 Composition
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 21. class A: def method(self): ... class B: def method(self): ... class C: def method(self): ... class You(A, B, C): def foo(self): self.method()
  • 22. class A: def method(self): self.bar() class B(A): def bar(self): ... class C(B): def bar(self): ... class You(C): def foo(self): self.method()
  • 23. class A: def method(self): self.bar() class B(A): def bar(self): .. class C(B): def bar(self): .. . . class You(C): def foo(self): self.method()
  • 24.
  • 25. — Architecture Patterns with Python, page 131
  • 26. — Architecture Patterns with Python, page 131
  • 27.
  • 30.
  • 32. class AbstractTrackingRepository(abc.ABC): def init (self): self.seen = set() @abc.abstractmethod def _add(self, product): raise NotImplementedError @abc.abstractmethod def _get(self, sku): raise NotImplementedError
  • 33. class AbstractTrackingRepository(abc.ABC): def init (self): self.seen = set() def add_product(self, product): self._add(product) self.seen.add(product) @abc.abstractmethod def _add(self, product): raise NotImplementedError @abc.abstractmethod def _get(self, sku): raise NotImplementedError
  • 34. class AbstractTrackingRepository(abc.ABC): def init (self): self.seen = set() def add_product(self, product): self._add(product) self.seen.add(product) def get_by_sku(self, sku): if product := self._get(sku): self.seen.add(product) return product @abc.abstractmethod def _add(self, product): raise NotImplementedError @abc.abstractmethod def _get(self, sku): raise NotImplementedError
  • 35.
  • 36. class FakeTrackingRepository(AbstractTrackingRepository): def init (self, products): super(). init () self._products = set(products)
  • 37. class FakeTrackingRepository(AbstractTrackingRepository): def init (self, products): super(). init () self._products = set(products) def _add(self, product): self._products.add(product) def _get(self, sku): return next(( p for p in self._products if p.sku == sku), None)
  • 38. class FakeTrackingRepository(AbstractTrackingRepository): def init (self, products): super(). init () self._products = set(products) def _add(self, product): self._products.add(product) def _get(self, sku): return next(( p for p in self._products if p.sku == sku), None)
  • 39.
  • 40. class AbstractTrackingRepository(abc.ABC): def init (self): self.seen = set() def add_product(self, product): self._add(product) self.seen.add(product) def get_by_sku(self, sku): if product := self._get(sku): self.seen.add(product) return product @abc.abstractmethod def _add(self, product): raise NotImplementedError @abc.abstractmethod def _get(self, sku): raise NotImplementedError
  • 41. class AbstractTrackingRepository(abc.ABC): def init (self): self.seen = set() def add_product(self, product): self._add(product) self.seen.add(product) def get_by_sku(self, sku): if product := self._get(sku): self.seen.add(product) return product @abc.abstractmethod def _add(self, product): raise NotImplementedError @abc.abstractmethod def _get(self, sku): raise NotImplementedError
  • 42. class AbstractRepository(abc.ABC): @abc.abstractmethod def add(self, product: Product) -> None: ... @abc.abstractmethod def get(self, sku: str) -> Product | None: ...
  • 43. class AbstractRepository(abc.ABC): @abc.abstractmethod def add(self, product: Product) -> None: ... @abc.abstractmethod def get(self, sku: str) -> Product | None: ... Nominal subtyping
  • 44. y(abc.ABC): Nominal subtyping class AbstractRepositor (metaclass=abc.ABCMeta): @abc.abstractmethod def add(self, product: Product) -> None: ... @abc.abstractmethod def get(self, sku: str) -> Product | None: ...
  • 45. @typing.runtime_checkable class Repository(typing.Protocol): def add(self, product: Product) -> None: ... def get(self, sku: str) -> Product | None: ...
  • 46. @typing.runtime_checkable class Repository(typing.Protocol): def add(self, product: Product) -> None: ... def get(self, sku: str) -> Product | None: ...
  • 47. @typing.runtime_checkable class Repository(typing.Protocol): def add(self, product: Product) -> None: ... def get(self, sku: str) -> Product | None: ... Structural subtyping
  • 48.
  • 49. class FakeRepository: def init (self, products): self._products = set(products)
  • 50. class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product)
  • 51. class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product)
  • 52. class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product) def get(self, sku: str) -> Product | None: return next(( p for p in self._products if p.sku == sku), None)
  • 53. class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product) def get(self, sku: str) -> Product | None: return next(( p for p in self._products if p.sku == sku), None)
  • 54. class FakeRepository(AbstractRepository): def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product) def get(self, sku: str) -> Product | None: return next(( p for p in self._products if p.sku == sku), None)
  • 55. class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product) def get(self, sku: str) -> Product | None: return next(( p for p in self._products if p.sku == sku), None) AbstractRepository.register(FakeRepository)
  • 56. @AbstractRepository.register class FakeRepository: def init (self, products): self._products = set(products) def add(self, product: Product ) -> None: self._products.add(product) def get(self, sku: str) -> Product | None: return next(( p for p in self._products if p.sku == sku), None)
  • 57.
  • 58. @dataclass class TrackingRepository: _repo: Repository seen: set[Product] = field(default_factory=set)
  • 59. @dataclass class TrackingRepository: _repo: Repository seen: set[Product] = field(default_factory=set) def add_product(self, product: Product) -> None: self._repo.add(product) self.seen.add(product)
  • 60. @dataclass class TrackingRepository: _repo: Repository seen: set[Product] = field(default_factory=set) def add_product(self, product: Product) -> None: self._repo.add(product) self.seen.add(product) def get_by_sku(self, sku: str) -> Product | None: if product := self._repo.get(sku): self.seen.add(product) return product
  • 61. @dataclass class TrackingRepository: _repo: Repository seen: set[Product] = field(default_factory=set) def add_product(self, product): self._repo.add(product) self.seen.add(product) def get_by_sku(self, sku): if product := self._repo.get(sku): self.seen.add(product) return product class FakeRepository: def init (self, products): self._products = set(products) def add(self, product): self._products.add(product) def get(self, sku): return next( ( p for p in self._products if p.sku == sku ), None )
  • 62.
  • 63.
  • 65. Subclassing requires knowledge + self-discipline Composition mechanically enforces discipline
  • 66.
  • 67. Namespaces are one honking great idea – let’s do more of those! — Uncle Timmy, Zen of Python, PEP 20
  • 68.
  • 69.
  • 71. def decorator(cls): cls.a = 42 return cls @decorator class C pass
  • 72. def decorator(cls): cls.a = 42 return cls @decorator class C pass assert hasattr(C, "a")
  • 73. def decorator(cls): cls.a = 42 return cls @decorator class C pass assert hasattr(C, "a") == C = decorator(_C)
  • 74.
  • 75. class Question(django.db.models.Model): question_text = CharField(max_length=200) pub_date = DateTimeField('date published')
  • 76. class Question(django.db.models.Model): question_text = CharField(max_length=200) pub_date = DateTimeField('date published') @dataclass @attrs.define class Question: question_text: str pub_date: datetime
  • 77. class Question(django.db.models.Model): question_text = CharField(max_length=200) pub_date = DateTimeField('date published') @dataclass class Question: question_text: str pub_date: datetime
  • 78. [' annotations ', ' class ', ' dataclass_fields ', ' dataclass_params ', ' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' match_args ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ', 'pub_date', 'question_text'] dir(Question("Hi!", today())) – dataclass Edition
  • 79. [' annotations ', ' class ', ' dataclass_fields ', ' dataclass_params ', ' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' match_args ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ', 'pub_date', 'question_text'] dir(Question("Hi!", today())) – dataclass Edition
  • 80. ['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getstate ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ', '_check_column_name_clashes', '_check_constraints', '_check_default_pk', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_expr_references', '_get_field_value_map', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state', 'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db', 'full_clean', 'get_constraints', 'get_deferred_fields', 'get_next_by_pub_date', 'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'pub_date', 'question_text', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_constraints', 'validate_unique'] dir(Question("Hi!", today())) – ORM Edition
  • 81. ['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getstate ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', ' lt ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ', '_check_column_name_clashes', '_check_constraints', '_check_default_pk', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_expr_references', '_get_field_value_map', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state', 'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db', 'full_clean', 'get_constraints', 'get_deferred_fields', 'get_next_by_pub_date', 'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'pub_date', 'question_text', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_constraints', 'validate_unique'] dir(Question("Hi!", today())) – ORM Edition
  • 82. class QuestionsRepository: conn: sqlalchemy.engine.Connection def get(self, id: int) -> Question: row = conn.execute( self. select( tables.questions.c.pub_date ).where( tables.questions.c.id == id ) ).one() return Question(id=id, pub_date=row.pub_date)
  • 83. -> Question class QuestionsRepository: conn: sqlalchemy.engine.Connection def get(self, id: int) : row = self.conn.execute( select( tables.questions.c.pub_date ).where( tables.questions.c.id == id ) ).one() return Question(id=id, pub_date=row.pub_date)
  • 84. class QuestionsRepository: conn: sqlalchemy.engine.Connection def get(self, id: int) -> Question: row = self.conn.execute( select( tables.questions.c.pub_date ).where( tables.questions.c.id == id ) ).one() return Question(id=id, pub_date=row.pub_date)
  • 85. ['DoesNotExist', 'MultipleObjectsReturned', ' class ', ' delattr ', ' dict ', getstate ', ' gt ', ' hash ', ' init ', ' init_subclass ', ' le ', lt ', ' module ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', setattr ', ' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' ' ' ' weakref ', '_check_column_name_clashes', '_check_constraints', '_check_default_pk', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_expr_references', '_get_field_value_map', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state', 'check', 'choice_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'from_db', 'full_clean', 'get_constraints', 'get_deferred_fields', 'get_next_by_pub_date', 'get_previous_by_pub_date', 'id', 'objects', 'pk', 'prepare_database_save', 'pub_date', 'question_text', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_constraints', 'validate_unique']
  • 86.
  • 91.
  • 92. Seth Michael Larson Working on urllib3 full-time for one week
  • 93. Programs are meant to be read by humans and only incidentally for computers to execute. — Abelson & Sussman, SICP Seth Michael Larson Working on urllib3 full-time for one week
  • 94.
  • 95.
  • 96.
  • 97. class A: b: B def other_method(): ... def method(self): self.other_method() self.b.even_other_method() class B: a: A def even_other_method(): ... def method(self): self.a.other_method() self.even_other_method() or
  • 98. class A: b: B def other_method(): ... def method(self): self.other_method() self.b.even_other_method() class B: a: A def even_other_method(): ... def method(self): self.a.other_method() self.even_other_method() or def function(a, b): a.other_method() b.even_other_method()
  • 99. class C: a: A b: B def method(self): self.a.other_method() self.b.even_other_method()
  • 100.
  • 101.
  • 106.
  • 108. class Mailbox: id: UUID addr: str pwd: str E-Mail Addresses
  • 109. class Mailbox: id: UUID addr: str pwd: str class Forwarder id: UUID addr: str targets: list[str] E-Mail Addresses
  • 110. class Mailbox: id: UUID addr: str pwd: str class Forwarder id: UUID addr: str targets: list[str] E-Mail Addresses EmailAddr = Forwarder | Mailbox
  • 111. class Mailbox: id: UUID addr: str pwd: str class Forwarder id: UUID addr: str targets: list[str] E-Mail Addresses EmailAddr = Forwarder | Mailbox
  • 112. Duplication is far cheaper than a wrong abstraction. — Sandi Metz
  • 113. Create one class, make fields optional
  • 114. class AddrType(enum.Enum): MAILBOX = "mailbox" FORWARDER = "forwarder" class EmailAddr type: AddrType id: UUID addr: str Create one class, make fields optional
  • 115. class AddrType(enum.Enum): MAILBOX = "mailbox" FORWARDER = "forwarder" class EmailAddr type: AddrType id: UUID addr: str # Only useful if type == AddrType.MAILBOX pwd: str | None # Only useful if type == AddrType.FORWARDER target: list[str] | None Create one class, make fields optional
  • 116. class AddrType(enum.Enum): MAILBOX = "mailbox" FORWARDER = "forwarder" class EmailAddr type: AddrType id: UUID addr: str # Only useful if type == AddrType.MAILBOX pwd: str | None # Only useful if type == AddrType.FORWARDER target: list[str] | None Create one class, make fields optional
  • 119. class EmailAddr: id: UUID addr: str class Mailbox email: EmailAddr pwd: str Composition
  • 120. class EmailAddr: id: UUID addr: str class Mailbox email: EmailAddr pwd: str class Forwarder email: EmailAddr targets: list[str] Composition
  • 121. class EmailAddr: id: UUID addr: str class Mailbox email: EmailAddr pwd: str class Forwarder email: EmailAddr targets: list[str] Composition
  • 122. class EmailAddr: id: UUID addr: str class Mailbox email: EmailAddr pwd: str class Forwarder email: EmailAddr targets: list[str] Composition
  • 123. Create a Common Base Class, Then Specialize
  • 124. class EmailAddr: id: UUID addr: str Create a Common Base Class, Then Specialize
  • 125. class EmailAddr: id: UUID addr: str class Mailbox(EmailAddr): pwd: str class Forwarder(EmailAddr): targets: list[str] Create a Common Base Class, Then Specialize
  • 126. class EmailAddr: id: UUID addr: str class Mailbox(EmailAddr): pwd: str class Forwarder(EmailAddr): targets: list[str] Create a Common Base Class, Then Specialize
  • 127.
  • 128. type EmailAddr struct { addr string } type Mailbox struct { EmailAddr pwd string }
  • 129. type EmailAddr struct { addr string } type Mailbox struct { EmailAddr pwd string } func main() { mbox := Mailbox{EmailAddr{"addr@example.com"}, "a hash"} fmt.Println(mbox.addr) }
  • 130. type EmailAddr struct { addr string } type Mailbox struct { EmailAddr pwd string } func main() { mbox := Mailbox{EmailAddr{"addr@example.com"}, "a hash"} fmt.Println(mbox.addr) }
  • 131.
  • 132.
  • 133.
  • 134.
  • 135. I never allow myself to have an opinion on anything that I don’t know the other side’s argument better than they do. — Charlie Munger
  • 136.