advanced-python-homework-2023/course_materials/04.DataModel.ipynb
2023-10-23 08:34:23 +03:00

37 KiB
Raw Permalink Blame History

Всё в Python является объектом

In [1]:
print(isinstance("add", object))
print(isinstance(1_000, object))
print(isinstance(3.14, object))
True

True

True
In [3]:
(3.14).as_integer_ratio()
Out[3]:
(7070651414971679, 2251799813685248)
In [13]:
class Vector2D:
    x = 0
    y = 0
    
    def norm(self):
        return (self.x**2 + self.y**2)**0.5

vec = Vector2D()
In [4]:
isinstance(vec, object)
Out[4]:
True
In [5]:
isinstance(Vector2D, object)
Out[5]:
True
In [4]:
isinstance(object, object)
Out[4]:
True
In [5]:
import math
isinstance(math, object)
Out[5]:
True
In [6]:
def add(a,b): return a + b
isinstance(add, object)
Out[6]:
True
In [7]:
add.x = 1

Магические методы

In [11]:
dir(vec)
Out[11]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'norm',
 'x',
 'y']
In [18]:
dir(add)
Out[18]:
['__annotations__',
 '__call__',
 '__class__',
 '__closure__',
 '__code__',
 '__defaults__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__get__',
 '__getattribute__',
 '__globals__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__kwdefaults__',
 '__le__',
 '__lt__',
 '__module__',
 '__name__',
 '__ne__',
 '__new__',
 '__qualname__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']
  • Управляют внутренней работой объектов
  • Хранят различную информацию объектов (которую можно получать в runtime)
  • Вызываются при использовании синтаксических конструкций
  • Вызываются встроенными (builtins) функциями
  • Область применения: перегрузка операторов, рефлексия и метапрограммирование
In [8]:
class TenItemList:

    def __len__(self):
        return 10


ten_item_list = TenItemList()
len(ten_item_list)
Out[8]:
10

Всё в Python является объектом, а все синтаксические конструкции сводятся к вызовам магических методов

Пример сложение

In [10]:
class Vector2D:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector2D(self.x + other.y, self.x + other.y)

    def norm(self):
        return (self.x**2 + self.y**2)**0.5

vec1 = Vector2D(1,2)
vec2 = Vector2D(3,4)
vec3 = vec1 + vec2
vec3.x, vec3.y
Out[10]:
(5, 5)

Пример присваивание

In [14]:
class Vector2D:
    x = 0
    y = 0
    
    def norm(self):
        return (self.x**2 + self.y**2)**0.5

vec = Vector2D()
In [15]:
vec = Vector2D()
vec.__getattribute__("x")
Out[15]:
0
In [17]:
vec.__getattribute__("norm")()
Out[17]:
0.0
In [18]:
vec.x = 5
vec.__getattribute__("x")
Out[18]:
5
In [19]:
vec.__setattr__("x", 10)
getattr(vec, "x")
Out[19]:
10
In [20]:
setattr(vec, "x", 20)
vec.x
Out[20]:
20
In [21]:
class Foo:
    def __setattr__(self, key, value):
        print(key, value)

foo = Foo()
foo.a = "A"
a A
In [22]:
foo.a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_35789/2615815247.py in <module>
----> 1 foo.a

AttributeError: 'Foo' object has no attribute 'a'

На самом деле все объекты реализованы как словари хранящие атрибуты объекта (однако есть возможности для оптимизаций)

In [23]:
class Vector2D:
    x = 0
    y = 0

    def norm(self):
        return (self.x**2 + self.y**2)**0.5

vec = Vector2D()
In [24]:
vec.__dict__
Out[24]:
{}
In [27]:
Vector2D.__dict__
Out[27]:
mappingproxy({'__module__': '__main__',
              'x': 0,
              'y': 0,
              'norm': <function __main__.Vector2D.norm(self)>,
              '__dict__': <attribute '__dict__' of 'Vector2D' objects>,
              '__weakref__': <attribute '__weakref__' of 'Vector2D' objects>,
              '__doc__': None})
In [26]:
vec.x = 5
vec.__dict__
Out[26]:
{'x': 5}

Модуль inspect --- информация об объектах в runtime

  • Не вся информация может быть доступна через магические методы
  • Недоступную информацию можно получить через модуль inspect
In [28]:
import inspect

def add(a,b): return a + b
inspect.isfunction(add)
Out[28]:
True
In [29]:
inspect.getsource(add)
Out[29]:
'def add(a,b): return a + b\n'
In [30]:
from numpy import random
inspect.getsource(random)
Out[30]:
'"""\n========================\nRandom Number Generation\n========================\n\nUse ``default_rng()`` to create a `Generator` and call its methods.\n\n=============== =========================================================\nGenerator\n--------------- ---------------------------------------------------------\nGenerator       Class implementing all of the random number distributions\ndefault_rng     Default constructor for ``Generator``\n=============== =========================================================\n\n============================================= ===\nBitGenerator Streams that work with Generator\n--------------------------------------------- ---\nMT19937\nPCG64\nPCG64DXSM\nPhilox\nSFC64\n============================================= ===\n\n============================================= ===\nGetting entropy to initialize a BitGenerator\n--------------------------------------------- ---\nSeedSequence\n============================================= ===\n\n\nLegacy\n------\n\nFor backwards compatibility with previous versions of numpy before 1.17, the\nvarious aliases to the global `RandomState` methods are left alone and do not\nuse the new `Generator` API.\n\n==================== =========================================================\nUtility functions\n-------------------- ---------------------------------------------------------\nrandom               Uniformly distributed floats over ``[0, 1)``\nbytes                Uniformly distributed random bytes.\npermutation          Randomly permute a sequence / generate a random sequence.\nshuffle              Randomly permute a sequence in place.\nchoice               Random sample from 1-D array.\n==================== =========================================================\n\n==================== =========================================================\nCompatibility\nfunctions - removed\nin the new API\n-------------------- ---------------------------------------------------------\nrand                 Uniformly distributed values.\nrandn                Normally distributed values.\nranf                 Uniformly distributed floating point numbers.\nrandom_integers      Uniformly distributed integers in a given range.\n                     (deprecated, use ``integers(..., closed=True)`` instead)\nrandom_sample        Alias for `random_sample`\nrandint              Uniformly distributed integers in a given range\nseed                 Seed the legacy random number generator.\n==================== =========================================================\n\n==================== =========================================================\nUnivariate\ndistributions\n-------------------- ---------------------------------------------------------\nbeta                 Beta distribution over ``[0, 1]``.\nbinomial             Binomial distribution.\nchisquare            :math:`\\\\chi^2` distribution.\nexponential          Exponential distribution.\nf                    F (Fisher-Snedecor) distribution.\ngamma                Gamma distribution.\ngeometric            Geometric distribution.\ngumbel               Gumbel distribution.\nhypergeometric       Hypergeometric distribution.\nlaplace              Laplace distribution.\nlogistic             Logistic distribution.\nlognormal            Log-normal distribution.\nlogseries            Logarithmic series distribution.\nnegative_binomial    Negative binomial distribution.\nnoncentral_chisquare Non-central chi-square distribution.\nnoncentral_f         Non-central F distribution.\nnormal               Normal / Gaussian distribution.\npareto               Pareto distribution.\npoisson              Poisson distribution.\npower                Power distribution.\nrayleigh             Rayleigh distribution.\ntriangular           Triangular distribution.\nuniform              Uniform distribution.\nvonmises             Von Mises circular distribution.\nwald                 Wald (inverse Gaussian) distribution.\nweibull              Weibull distribution.\nzipf                 Zipf\'s distribution over ranked data.\n==================== =========================================================\n\n==================== ==========================================================\nMultivariate\ndistributions\n-------------------- ----------------------------------------------------------\ndirichlet            Multivariate generalization of Beta distribution.\nmultinomial          Multivariate generalization of the binomial distribution.\nmultivariate_normal  Multivariate generalization of the normal distribution.\n==================== ==========================================================\n\n==================== =========================================================\nStandard\ndistributions\n-------------------- ---------------------------------------------------------\nstandard_cauchy      Standard Cauchy-Lorentz distribution.\nstandard_exponential Standard exponential distribution.\nstandard_gamma       Standard Gamma distribution.\nstandard_normal      Standard normal distribution.\nstandard_t           Standard Student\'s t-distribution.\n==================== =========================================================\n\n==================== =========================================================\nInternal functions\n-------------------- ---------------------------------------------------------\nget_state            Get tuple representing internal state of generator.\nset_state            Set state of generator.\n==================== =========================================================\n\n\n"""\n__all__ = [\n    \'beta\',\n    \'binomial\',\n    \'bytes\',\n    \'chisquare\',\n    \'choice\',\n    \'dirichlet\',\n    \'exponential\',\n    \'f\',\n    \'gamma\',\n    \'geometric\',\n    \'get_state\',\n    \'gumbel\',\n    \'hypergeometric\',\n    \'laplace\',\n    \'logistic\',\n    \'lognormal\',\n    \'logseries\',\n    \'multinomial\',\n    \'multivariate_normal\',\n    \'negative_binomial\',\n    \'noncentral_chisquare\',\n    \'noncentral_f\',\n    \'normal\',\n    \'pareto\',\n    \'permutation\',\n    \'poisson\',\n    \'power\',\n    \'rand\',\n    \'randint\',\n    \'randn\',\n    \'random\',\n    \'random_integers\',\n    \'random_sample\',\n    \'ranf\',\n    \'rayleigh\',\n    \'sample\',\n    \'seed\',\n    \'set_state\',\n    \'shuffle\',\n    \'standard_cauchy\',\n    \'standard_exponential\',\n    \'standard_gamma\',\n    \'standard_normal\',\n    \'standard_t\',\n    \'triangular\',\n    \'uniform\',\n    \'vonmises\',\n    \'wald\',\n    \'weibull\',\n    \'zipf\',\n]\n\n# add these for module-freeze analysis (like PyInstaller)\nfrom . import _pickle\nfrom . import _common\nfrom . import _bounded_integers\n\nfrom ._generator import Generator, default_rng\nfrom .bit_generator import SeedSequence, BitGenerator\nfrom ._mt19937 import MT19937\nfrom ._pcg64 import PCG64, PCG64DXSM\nfrom ._philox import Philox\nfrom ._sfc64 import SFC64\nfrom .mtrand import *\n\n__all__ += [\'Generator\', \'RandomState\', \'SeedSequence\', \'MT19937\',\n            \'Philox\', \'PCG64\', \'PCG64DXSM\', \'SFC64\', \'default_rng\',\n            \'BitGenerator\']\n\n\ndef __RandomState_ctor():\n    """Return a RandomState instance.\n\n    This function exists solely to assist (un)pickling.\n\n    Note that the state of the RandomState returned here is irrelevant, as this\n    function\'s entire purpose is to return a newly allocated RandomState whose\n    state pickle can set.  Consequently the RandomState returned by this function\n    is a freshly allocated copy with a seed=0.\n\n    See https://github.com/numpy/numpy/issues/4763 for a detailed discussion\n\n    """\n    return RandomState(seed=0)\n\n\nfrom numpy._pytesttester import PytestTester\ntest = PytestTester(__name__)\ndel PytestTester\n'

Модуль inspect --- информация об объектах в runtime

  • Не вся информация может быть доступна через магические методы
  • Недоступную информацию можно получить через модуль inspect
In [2]:
import inspect

def add(a,b): return a + b
inspect.isfunction(add)
Out[2]:
True
In [12]:
inspect.getsource(add)
Out[12]:
'def add(a,b): return a + b\n'
In [3]:
from numpy import random
inspect.getsource(random)
Out[3]:
'"""\n========================\nRandom Number Generation\n========================\n\nUse ``default_rng()`` to create a `Generator` and call its methods.\n\n=============== =========================================================\nGenerator\n--------------- ---------------------------------------------------------\nGenerator       Class implementing all of the random number distributions\ndefault_rng     Default constructor for ``Generator``\n=============== =========================================================\n\n============================================= ===\nBitGenerator Streams that work with Generator\n--------------------------------------------- ---\nMT19937\nPCG64\nPCG64DXSM\nPhilox\nSFC64\n============================================= ===\n\n============================================= ===\nGetting entropy to initialize a BitGenerator\n--------------------------------------------- ---\nSeedSequence\n============================================= ===\n\n\nLegacy\n------\n\nFor backwards compatibility with previous versions of numpy before 1.17, the\nvarious aliases to the global `RandomState` methods are left alone and do not\nuse the new `Generator` API.\n\n==================== =========================================================\nUtility functions\n-------------------- ---------------------------------------------------------\nrandom               Uniformly distributed floats over ``[0, 1)``\nbytes                Uniformly distributed random bytes.\npermutation          Randomly permute a sequence / generate a random sequence.\nshuffle              Randomly permute a sequence in place.\nchoice               Random sample from 1-D array.\n==================== =========================================================\n\n==================== =========================================================\nCompatibility\nfunctions - removed\nin the new API\n-------------------- ---------------------------------------------------------\nrand                 Uniformly distributed values.\nrandn                Normally distributed values.\nranf                 Uniformly distributed floating point numbers.\nrandom_integers      Uniformly distributed integers in a given range.\n                     (deprecated, use ``integers(..., closed=True)`` instead)\nrandom_sample        Alias for `random_sample`\nrandint              Uniformly distributed integers in a given range\nseed                 Seed the legacy random number generator.\n==================== =========================================================\n\n==================== =========================================================\nUnivariate\ndistributions\n-------------------- ---------------------------------------------------------\nbeta                 Beta distribution over ``[0, 1]``.\nbinomial             Binomial distribution.\nchisquare            :math:`\\\\chi^2` distribution.\nexponential          Exponential distribution.\nf                    F (Fisher-Snedecor) distribution.\ngamma                Gamma distribution.\ngeometric            Geometric distribution.\ngumbel               Gumbel distribution.\nhypergeometric       Hypergeometric distribution.\nlaplace              Laplace distribution.\nlogistic             Logistic distribution.\nlognormal            Log-normal distribution.\nlogseries            Logarithmic series distribution.\nnegative_binomial    Negative binomial distribution.\nnoncentral_chisquare Non-central chi-square distribution.\nnoncentral_f         Non-central F distribution.\nnormal               Normal / Gaussian distribution.\npareto               Pareto distribution.\npoisson              Poisson distribution.\npower                Power distribution.\nrayleigh             Rayleigh distribution.\ntriangular           Triangular distribution.\nuniform              Uniform distribution.\nvonmises             Von Mises circular distribution.\nwald                 Wald (inverse Gaussian) distribution.\nweibull              Weibull distribution.\nzipf                 Zipf\'s distribution over ranked data.\n==================== =========================================================\n\n==================== ==========================================================\nMultivariate\ndistributions\n-------------------- ----------------------------------------------------------\ndirichlet            Multivariate generalization of Beta distribution.\nmultinomial          Multivariate generalization of the binomial distribution.\nmultivariate_normal  Multivariate generalization of the normal distribution.\n==================== ==========================================================\n\n==================== =========================================================\nStandard\ndistributions\n-------------------- ---------------------------------------------------------\nstandard_cauchy      Standard Cauchy-Lorentz distribution.\nstandard_exponential Standard exponential distribution.\nstandard_gamma       Standard Gamma distribution.\nstandard_normal      Standard normal distribution.\nstandard_t           Standard Student\'s t-distribution.\n==================== =========================================================\n\n==================== =========================================================\nInternal functions\n-------------------- ---------------------------------------------------------\nget_state            Get tuple representing internal state of generator.\nset_state            Set state of generator.\n==================== =========================================================\n\n\n"""\n__all__ = [\n    \'beta\',\n    \'binomial\',\n    \'bytes\',\n    \'chisquare\',\n    \'choice\',\n    \'dirichlet\',\n    \'exponential\',\n    \'f\',\n    \'gamma\',\n    \'geometric\',\n    \'get_state\',\n    \'gumbel\',\n    \'hypergeometric\',\n    \'laplace\',\n    \'logistic\',\n    \'lognormal\',\n    \'logseries\',\n    \'multinomial\',\n    \'multivariate_normal\',\n    \'negative_binomial\',\n    \'noncentral_chisquare\',\n    \'noncentral_f\',\n    \'normal\',\n    \'pareto\',\n    \'permutation\',\n    \'poisson\',\n    \'power\',\n    \'rand\',\n    \'randint\',\n    \'randn\',\n    \'random\',\n    \'random_integers\',\n    \'random_sample\',\n    \'ranf\',\n    \'rayleigh\',\n    \'sample\',\n    \'seed\',\n    \'set_state\',\n    \'shuffle\',\n    \'standard_cauchy\',\n    \'standard_exponential\',\n    \'standard_gamma\',\n    \'standard_normal\',\n    \'standard_t\',\n    \'triangular\',\n    \'uniform\',\n    \'vonmises\',\n    \'wald\',\n    \'weibull\',\n    \'zipf\',\n]\n\n# add these for module-freeze analysis (like PyInstaller)\nfrom . import _pickle\nfrom . import _common\nfrom . import _bounded_integers\n\nfrom ._generator import Generator, default_rng\nfrom .bit_generator import SeedSequence, BitGenerator\nfrom ._mt19937 import MT19937\nfrom ._pcg64 import PCG64, PCG64DXSM\nfrom ._philox import Philox\nfrom ._sfc64 import SFC64\nfrom .mtrand import *\n\n__all__ += [\'Generator\', \'RandomState\', \'SeedSequence\', \'MT19937\',\n            \'Philox\', \'PCG64\', \'PCG64DXSM\', \'SFC64\', \'default_rng\',\n            \'BitGenerator\']\n\n\ndef __RandomState_ctor():\n    """Return a RandomState instance.\n\n    This function exists solely to assist (un)pickling.\n\n    Note that the state of the RandomState returned here is irrelevant, as this\n    function\'s entire purpose is to return a newly allocated RandomState whose\n    state pickle can set.  Consequently the RandomState returned by this function\n    is a freshly allocated copy with a seed=0.\n\n    See https://github.com/numpy/numpy/issues/4763 for a detailed discussion\n\n    """\n    return RandomState(seed=0)\n\n\nfrom numpy._pytesttester import PytestTester\ntest = PytestTester(__name__)\ndel PytestTester\n'
In [ ]: