{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp core.foundation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "from local.test import *\n", "from local.core.imports import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from local.notebook.showdoc import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Core\n", "\n", "> Basic functions used in the fastai library" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "defaults = SimpleNamespace()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Metaclasses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See this [blog post](https://realpython.com/python-metaclasses/) for more information about metaclasses. \n", "- `PrePostInitMeta` ensures that the classes defined with it run `__pre_init__` and `__post_init__` (without having to write `self.__pre_init__()` and `self.__post_init__()` in the actual `init`\n", "- `NewChkMeta` gives the `PrePostInitMeta` functionality and ensures classes defined with it don't re-create an object of their type whenever it's passed to the constructor\n", "- `BypassNewMeta` ensures classes defined with it can easily be casted form objects they subclass." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class FixSigMeta(type):\n", " \"A metaclass that fixes the signature on classes that override __new__\"\n", " def __new__(cls, name, bases, dict):\n", " res = super().__new__(cls, name, bases, dict)\n", " if res.__init__ is not object.__init__: res.__signature__ = inspect.signature(res.__init__)\n", " return res" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class PrePostInitMeta(FixSigMeta):\n", " \"A metaclass that calls optional `__pre_init__` and `__post_init__` methods\"\n", " def __call__(cls, *args, **kwargs):\n", " res = cls.__new__(cls)\n", " if type(res)==cls:\n", " if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)\n", " res.__init__(*args,**kwargs)\n", " if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)\n", " return res" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
class
PrePostInitMeta
[source]PrePostInitMeta
(**`name`**, **`bases`**, **`dict`**) :: [`FixSigMeta`](/core.foundation.html#FixSigMeta)\n",
"\n",
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"
],
"text/plain": [
"is_iter
[source]is_iter
(**`o`**)\n",
"\n",
"Test whether `o` can be used in a `for` loop"
],
"text/plain": [
"L.__getitem__
[source]L.__getitem__
(**`idx`**)\n",
"\n",
"Retrieve `idx` (can be list of indices, or mask, or int) items"
],
"text/plain": [
"L.__setitem__
[source]L.__setitem__
(**`idx`**, **`o`**)\n",
"\n",
"Set `idx` (can be list of indices, or mask, or int) items to `o` (which is broadcast if not iterable)"
],
"text/plain": [
"L.unique
[source]L.unique
()\n",
"\n",
"Unique items, in stable order"
],
"text/plain": [
"L.val2idx
[source]L.val2idx
()\n",
"\n",
"Dict from value to index"
],
"text/plain": [
"L.filter
[source]L.filter
(**`f`**, **`negate`**=*`False`*, **\\*\\*`kwargs`**)\n",
"\n",
"Create new [`L`](/core.html#L) filtered by predicate `f`, passing `args` and `kwargs` to `f`"
],
"text/plain": [
"L.map
[source]L.map
(**`f`**, **\\*`args`**, **\\*\\*`kwargs`**)\n",
"\n",
"Create new [`L`](/core.html#L) with `f` applied to all `items`, passing `args` and `kwargs` to `f`"
],
"text/plain": [
"L.map_dict
[source]L.map_dict
(**`f`**=*`'noop'`*, **\\*`args`**, **\\*\\*`kwargs`**)\n",
"\n",
"Like `map`, but creates a dict from `items` to function results"
],
"text/plain": [
"L.zip
[source]L.zip
(**`cycled`**=*`False`*)\n",
"\n",
"Create new [`L`](/core.html#L) with `zip(*items)`"
],
"text/plain": [
"L.map_zip
[source]L.map_zip
(**`f`**, **\\*`args`**, **`cycled`**=*`False`*, **\\*\\*`kwargs`**)\n",
"\n",
"Combine `zip` and `starmap`"
],
"text/plain": [
"L.zipwith
[source]L.zipwith
(**\\*`rest`**, **`cycled`**=*`False`*)\n",
"\n",
"Create new [`L`](/core.html#L) with `self` zip with each of `*rest`"
],
"text/plain": [
"L.map_zipwith
[source]L.map_zipwith
(**`f`**, **\\*`rest`**, **`cycled`**=*`False`*, **\\*\\*`kwargs`**)\n",
"\n",
"Combine `zipwith` and `starmap`"
],
"text/plain": [
"L.itemgot
[source]L.itemgot
(**\\*`idxs`**)\n",
"\n",
"Create new [`L`](/core.html#L) with item `idx` of all `items`"
],
"text/plain": [
"L.attrgot
[source]L.attrgot
(**`k`**, **`default`**=*`None`*)\n",
"\n",
"Create new [`L`](/core.html#L) with attr `k` of all `items`"
],
"text/plain": [
"L.sorted
[source]L.sorted
(**`key`**=*`None`*, **`reverse`**=*`False`*)\n",
"\n",
"New [`L`](/core.html#L) sorted by `key`. If key is str then use `attrgetter`. If key is int then use `itemgetter`"
],
"text/plain": [
"L.split
[source]L.split
(**`s`**, **`sep`**=*`None`*, **`maxsplit`**=*`-1`*)\n",
"\n",
"Same as `str.split`, but returns an [`L`](/core.html#L)"
],
"text/plain": [
"L.range
[source]L.range
(**`a`**, **`b`**=*`None`*, **`step`**=*`None`*)\n",
"\n",
"Same as `range`, but returns an [`L`](/core.html#L). Can pass a collection for `a`, to use `len(a)`"
],
"text/plain": [
"L.concat
[source]L.concat
()\n",
"\n",
"Concatenate all elements of list"
],
"text/plain": [
"L.copy
[source]L.copy
()\n",
"\n",
"Same as `list.copy`, but returns an [`L`](/core.html#L)"
],
"text/plain": [
"