diff --git a/08_python/README.md b/08_python/README.md new file mode 100644 index 0000000..fea29ff --- /dev/null +++ b/08_python/README.md @@ -0,0 +1,11 @@ +### Практика про классы в питоне + +Что здесь есть полезного? +- [descriptor](./descriptor) -- про модификаторы и как использовать `@property`; +- [mro](./mro) -- method resolution order или примеры про плату за сомнительные решения; +- [definition](./definition) -- определения классов; +- [magic](./magic) -- куча примеров магических методов; +- [mixins](./mixins) -- пример паттерна mixin; +- [class-deco](./class-deco) -- как использовать класс в качестве декоратора; +- [dataclasses](./dataclasses) -- датаклассы (классы без методов, но только с +данными); diff --git a/08_python/class-deco/getter.py b/08_python/class-deco/getter.py new file mode 100644 index 0000000..cea07be --- /dev/null +++ b/08_python/class-deco/getter.py @@ -0,0 +1,15 @@ +class ClassDeco: + def __init__(self, f): + self.f = f + + def __call__(self, *args, **kwargs): + print(self.f, args, kwargs) + return self.f(*args, **kwargs) + + +@ClassDeco +def foo(): + return 45 + + +# foo = ClassDeco(foo) diff --git a/08_python/dataclasses/dcls.py b/08_python/dataclasses/dcls.py new file mode 100644 index 0000000..04e9ba5 --- /dev/null +++ b/08_python/dataclasses/dcls.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass +from typing import Union + + +# def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, +# unsafe_hash=False, frozen=False): +# """Returns the same class as was passed in, with dunder methods +# added based on the fields defined in the class. +# +# Examines PEP 526 __annotations__ to determine fields. +# +# If init is true, an __init__() method is added to the class. If +# repr is true, a __repr__() method is added. If order is true, rich +# comparison dunder methods are added. If unsafe_hash is true, a +# __hash__() method function is added. If frozen is true, fields may +# not be assigned to after instance creation. +# """ + + +@dataclass(frozen=True) +class A: + a: int + b: bool + c: str = "asd" + f: Union[int, bool, str] = 0 + + def foo(self): + print(self) diff --git a/08_python/definition/cl_defo.py b/08_python/definition/cl_defo.py new file mode 100644 index 0000000..1caa0b5 --- /dev/null +++ b/08_python/definition/cl_defo.py @@ -0,0 +1,17 @@ +class A: + pass + + +class C: + a, b = 1, 1 + for i in range(15): + a, b = b, a + b + + print(a) + f = lambda self, a: a + g = lambda self, a: self.f(a) + + def __init__(self, x, y): + print(self) + self.x = x + self.y = y diff --git a/08_python/definition/dct.py b/08_python/definition/dct.py new file mode 100644 index 0000000..19582f4 --- /dev/null +++ b/08_python/definition/dct.py @@ -0,0 +1,7 @@ +class A: + n = 5 + e = 50 + f = lambda self: 42 + + def __init__(self): + self.a = 1000 diff --git a/08_python/definition/def_cls.py b/08_python/definition/def_cls.py new file mode 100644 index 0000000..2fc3275 --- /dev/null +++ b/08_python/definition/def_cls.py @@ -0,0 +1,12 @@ +class C: + f = 50 + + a, b = 1, 1 + for _ in range(10): + a, b = b, a + b + print(a, b) + + def __init__(self, a, b): + print(self) + self.a = a + self.b = b diff --git a/08_python/definition/inheritance.py b/08_python/definition/inheritance.py new file mode 100644 index 0000000..b78179c --- /dev/null +++ b/08_python/definition/inheritance.py @@ -0,0 +1,14 @@ +# class Base(object) +class Base: + def foo(self): + return 42 + + +class NotBase: + def foo(self): + return 43 + + +class A(NotBase, Base): + def bar(self): + return 41 diff --git a/08_python/descriptor/modifiers.py b/08_python/descriptor/modifiers.py new file mode 100644 index 0000000..735eb77 --- /dev/null +++ b/08_python/descriptor/modifiers.py @@ -0,0 +1,17 @@ +class A: + def __init__(self, a, b): + self._a = a + self.__b = b + + @property + def super_duper_var(self): + print(self) + return self.__b + + @super_duper_var.setter + def super_duper_var(self, value): + self.__b = value + + # @super_duper_var.deleter + # def super_duper_var(self): + # pass diff --git a/08_python/magic/MyHashable.py b/08_python/magic/MyHashable.py new file mode 100644 index 0000000..9986a65 --- /dev/null +++ b/08_python/magic/MyHashable.py @@ -0,0 +1,8 @@ +from abc import ABC + + +class MyHashable(ABC): + @classmethod + def __subclasshook__(cls, sbcls): + hash_func = getattr(sbcls, "__hash__", None) + return hash_func is not None diff --git a/08_python/magic/always_field.py b/08_python/magic/always_field.py new file mode 100644 index 0000000..cd6cf29 --- /dev/null +++ b/08_python/magic/always_field.py @@ -0,0 +1,3 @@ +class AlwaysHaveField: + def __getattr__(self, value): + return value diff --git a/08_python/magic/ex_for.py b/08_python/magic/ex_for.py new file mode 100644 index 0000000..0c1d8fa --- /dev/null +++ b/08_python/magic/ex_for.py @@ -0,0 +1,23 @@ +class Iterator: + def __init__(self, origin_list): + self._ref = origin_list + self.n = -1 + + def __next__(self): + if self.n < len(self._ref) - 1: + self.n += 1 + return self._ref[self.n] + raise StopIteration() + + +class A: + def __init__(self): + self.a = [1, 2, 3, 4] + + def __iter__(self): + return Iterator(self.a) + + +a = A() +for el in a: + print(el) diff --git a/08_python/magic/ex_for2.py b/08_python/magic/ex_for2.py new file mode 100644 index 0000000..5bfb2e7 --- /dev/null +++ b/08_python/magic/ex_for2.py @@ -0,0 +1,11 @@ +class A: + def __init__(self): + self.a = [1, 2, 3, 4] + + def __getitem__(self, ind): + return self.a[ind] + + +a = A() +for el in a: + print(el) diff --git a/08_python/magic/hasheq.py b/08_python/magic/hasheq.py new file mode 100644 index 0000000..6364d42 --- /dev/null +++ b/08_python/magic/hasheq.py @@ -0,0 +1,20 @@ +class MADATA: + def __init__( + self, + a: int, + b: int, + c: int, + ): + self.a = a + self.b = b + self.c = c + + @property + def _tup_view(self): + return self.a, self.b, self.c + + def __hash__(self): + return hash(self._tup_view) + + def __eq__(self, o): + return isinstance(o, type(self)) and o._tup_view == self._tup_view diff --git a/08_python/magic/new_getattr.py b/08_python/magic/new_getattr.py new file mode 100644 index 0000000..76f4d2f --- /dev/null +++ b/08_python/magic/new_getattr.py @@ -0,0 +1,11 @@ +class A: + def __init__(self): + self.a = 1 + self.b = 2 + + def foo(self): + print("Hello") + + def __getattr__(self, name): + print(f"Called __getattr__ with arg: {name}") + return name diff --git a/08_python/magic/nmp.py b/08_python/magic/nmp.py new file mode 100644 index 0000000..afa1719 --- /dev/null +++ b/08_python/magic/nmp.py @@ -0,0 +1,6 @@ +class DF: + def __getitem__(self, key): + return key + + def __setitem__(self, key, value): + print(key, value) diff --git a/08_python/mixins/cat_girl.py b/08_python/mixins/cat_girl.py new file mode 100644 index 0000000..a7e500b --- /dev/null +++ b/08_python/mixins/cat_girl.py @@ -0,0 +1,14 @@ +class GirlsMixin: + def hooray(self): + print("Hoooray") + + +class CatMixin: + def feed(self, hp): + print("Meow") + + +class CatGirls(GirlsMixin, CatMixin): + def main(self): + super().feed(50) + super().hooray() diff --git a/08_python/mixins/completely_f_cked.py b/08_python/mixins/completely_f_cked.py new file mode 100644 index 0000000..eb1e9c7 --- /dev/null +++ b/08_python/mixins/completely_f_cked.py @@ -0,0 +1,21 @@ +class Base: + def __init__(self, a): + self.x = a + + +class A(Base): + def __init__(self): + super().__init__(5) + + +class B(Base): + def __init__(self, x): + super().__init__(x) + + +class C(A, B): + ... + + +class D(B, A): + ... diff --git a/08_python/mro/broken_mro.py b/08_python/mro/broken_mro.py new file mode 100644 index 0000000..c56d383 --- /dev/null +++ b/08_python/mro/broken_mro.py @@ -0,0 +1,34 @@ +class Base: + def foo(self): + print("Base") + + +class A(Base): + def foo(self): + print("A") + super().foo() + + +class B(Base): + def foo(self): + print("B") + super().foo() + + +class C(A, B): + def foo(self): + print("C") + super().foo() + + +class D(B, A): + def foo(self): + print("D") + super().foo() + + +class E(C, D): + pass + + +print("HEELLO") diff --git a/08_python/mro/mro.py b/08_python/mro/mro.py new file mode 100644 index 0000000..1494760 --- /dev/null +++ b/08_python/mro/mro.py @@ -0,0 +1,24 @@ +class Base: + def foo(self): + print("Base") + + +class A(Base): + def foo(self): + print("A") + super().foo() + + +class B(Base): + def foo(self): + print("B") + super().foo() + + +class C(A, B): + def foo(self): + print("C") + super().foo() + + +print("HEELLO")