mirror of
https://github.com/rasbt/python_reference.git
synced 2025-01-31 05:33:47 +00:00
metaclasses section
This commit is contained in:
parent
c8466e606c
commit
81610f64f6
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "",
|
"name": "",
|
||||||
"signature": "sha256:9a07a78204a51f0faab65e52657f0446cd604ed470627f9c6af1ba74c047fe23"
|
"signature": "sha256:92f953fd8004f1dd1e9969ce61096f5a0b43190de3f3c7c8f85642b667754fae"
|
||||||
},
|
},
|
||||||
"nbformat": 3,
|
"nbformat": 3,
|
||||||
"nbformat_minor": 0,
|
"nbformat_minor": 0,
|
||||||
|
@ -81,7 +81,9 @@
|
||||||
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)\n",
|
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)\n",
|
||||||
"- [Abortive statements in `finally` blocks](#finally_blocks)\n",
|
"- [Abortive statements in `finally` blocks](#finally_blocks)\n",
|
||||||
"- [Assigning types to variables as values](#variable_types)\n",
|
"- [Assigning types to variables as values](#variable_types)\n",
|
||||||
"- [Keyword argument unpacking syntax - `*args` and `**kwargs`](#splat_op)"
|
"- [Only the first clause of generators is evaluated immediately](#generator_rhs)\n",
|
||||||
|
"- [Keyword argument unpacking syntax - `*args` and `**kwargs`](#splat_op)\n",
|
||||||
|
"- [Metaclasses - What creates a new instance of a class?](#new_instance)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -275,13 +277,13 @@
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"input": [
|
"input": [
|
||||||
"a_list = []\n",
|
"a_list = []\n",
|
||||||
"print('ID:',id(a_list))\n",
|
"print(a_list, '\\nID (initial):',id(a_list), '\\n')\n",
|
||||||
"\n",
|
"\n",
|
||||||
"a_list.append(1)\n",
|
"a_list.append(1)\n",
|
||||||
"print('ID (append):',id(a_list))\n",
|
"print(a_list, '\\nID (append):',id(a_list), '\\n')\n",
|
||||||
"\n",
|
"\n",
|
||||||
"a_list.append(2)\n",
|
"a_list.extend([2])\n",
|
||||||
"print('ID (extend):',id(a_list))"
|
"print(a_list, '\\nID (extend):',id(a_list))"
|
||||||
],
|
],
|
||||||
"language": "python",
|
"language": "python",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -290,13 +292,18 @@
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"stream": "stdout",
|
"stream": "stdout",
|
||||||
"text": [
|
"text": [
|
||||||
"ID: 4366495544\n",
|
"[] \n",
|
||||||
"ID (append): 4366495544\n",
|
"ID (initial): 140704077653128 \n",
|
||||||
"ID (extend): 4366495544\n"
|
"\n",
|
||||||
|
"[1] \n",
|
||||||
|
"ID (append): 140704077653128 \n",
|
||||||
|
"\n",
|
||||||
|
"[1, 2] \n",
|
||||||
|
"ID (extend): 140704077653128\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prompt_number": 7
|
"prompt_number": 6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
@ -2980,6 +2987,109 @@
|
||||||
],
|
],
|
||||||
"prompt_number": 4
|
"prompt_number": 4
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<br>\n",
|
||||||
|
"<br>\n",
|
||||||
|
"<a name='generator_rhs'></a>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Only the first clause of generators is evaluated immediately"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"[[back to top](#sections)]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"The main reason why we love to use generators in certain cases (i.e., when we are dealing with large numbers of computations) is that it only computes the next value when it is needed, which is also known as \"lazy\" evaluation.\n",
|
||||||
|
"However, the first clause of an generator is already checked upon it's creation, as the following example demonstrates:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"gen_fails = (i for i in 1/0)"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"ename": "ZeroDivisionError",
|
||||||
|
"evalue": "division by zero",
|
||||||
|
"output_type": "pyerr",
|
||||||
|
"traceback": [
|
||||||
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
|
||||||
|
"\u001b[0;32m<ipython-input-18-29312e1ece8d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mgen_fails\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||||
|
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Certainly, this is a nice feature, since it notifies us about syntax erros immediately. However, this is (unfortunately) not the case if we have multiple cases in our generator."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"gen_succeeds = (i for i in range(5) for j in 1/0)"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"prompt_number": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"print('But obviously fails when we iterate ...')\n",
|
||||||
|
"for i in gen_succeeds:\n",
|
||||||
|
" print(i)"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"ename": "ZeroDivisionError",
|
||||||
|
"evalue": "division by zero",
|
||||||
|
"output_type": "pyerr",
|
||||||
|
"traceback": [
|
||||||
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
|
||||||
|
"\u001b[0;32m<ipython-input-20-8a83a1022971>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'But obviously fails when we iterate ...'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mgen_succeeds\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||||||
|
"\u001b[0;32m<ipython-input-19-c54c53f2218a>\u001b[0m in \u001b[0;36m<genexpr>\u001b[0;34m(.0)\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mgen_succeeds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||||
|
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"But obviously fails when we iterate ...\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 20
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -2996,6 +3106,13 @@
|
||||||
"##Keyword argument unpacking syntax - `*args` and `**kwargs`"
|
"##Keyword argument unpacking syntax - `*args` and `**kwargs`"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"[[back to top](#sections)]"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -3034,7 +3151,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prompt_number": 30
|
"prompt_number": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
|
@ -3062,12 +3179,12 @@
|
||||||
"stream": "stdout",
|
"stream": "stdout",
|
||||||
"text": [
|
"text": [
|
||||||
"type of kwargs: <class 'dict'>\n",
|
"type of kwargs: <class 'dict'>\n",
|
||||||
"kwargs contents: {'d': 4, 'c': 3, 'b': 2, 'a': 1}\n",
|
"kwargs contents: {'b': 2, 'a': 1, 'c': 3, 'd': 4}\n",
|
||||||
"value of argument a: 1\n"
|
"value of argument a: 1\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prompt_number": 35
|
"prompt_number": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
|
@ -3097,7 +3214,176 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prompt_number": 36
|
"prompt_number": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a name=\"new_instance\"></a>\n",
|
||||||
|
"<br>\n",
|
||||||
|
"<br>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Metaclasses - What creates a new instance of a class?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Usually, it is the `__init__` method when we think of instanciating a new object from a class. However, it is the static method `__new__` (it is not a class method!) that creates and returns a new instance before `__init__()` is called. \n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"`__new__` is a so-called static method that returns \n",
|
||||||
|
"`return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)`"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"print(help(object.__new__))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"Help on built-in function __new__:\n",
|
||||||
|
"\n",
|
||||||
|
"__new__(...)\n",
|
||||||
|
" T.__new__(S, ...) -> a new object with type S, a subtype of T\n",
|
||||||
|
"\n",
|
||||||
|
"None\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"print(dir(object))\n",
|
||||||
|
"print(help(object.__new__))\n",
|
||||||
|
"print(help(object.__init__))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']\n",
|
||||||
|
"Help on built-in function __new__:\n",
|
||||||
|
"\n",
|
||||||
|
"__new__(...)\n",
|
||||||
|
" T.__new__(S, ...) -> a new object with type S, a subtype of T\n",
|
||||||
|
"\n",
|
||||||
|
"None\n",
|
||||||
|
"Help on wrapper_descriptor:\n",
|
||||||
|
"\n",
|
||||||
|
"__init__(...)\n",
|
||||||
|
" x.__init__(...) initializes x; see help(type(x)) for signature\n",
|
||||||
|
"\n",
|
||||||
|
"None\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"class a_class(object):\n",
|
||||||
|
" def __new__(clss, *args, **kwargs):\n",
|
||||||
|
" print('excecuted __new__')\n",
|
||||||
|
" return None\n",
|
||||||
|
" def __init__(self, an_arg):\n",
|
||||||
|
" print('excecuted __init__')\n",
|
||||||
|
" self.an_arg = an_arg\n",
|
||||||
|
" \n",
|
||||||
|
"a_object = a_class(1)\n",
|
||||||
|
"print('Type of a_object:', type(a_object))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"excecuted __new__\n",
|
||||||
|
"Type of a_object: <class 'NoneType'>\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"class a_class(object):\n",
|
||||||
|
" def __new__(clss, *args, **kwargs):\n",
|
||||||
|
" print('excecuted __new__')\n",
|
||||||
|
" inst = super(a_class, clss).__new__(clss, *args, **kwargs)\n",
|
||||||
|
" return inst\n",
|
||||||
|
" def __init__(self):\n",
|
||||||
|
" print('excecuted __init__')\n",
|
||||||
|
" \n",
|
||||||
|
"a_object = a_class()\n",
|
||||||
|
"print('Type of a_object:', type(a_object))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"excecuted __new__\n",
|
||||||
|
"excecuted __init__\n",
|
||||||
|
"Type of a_object: <class '__main__.a_class'>\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"class a_class(object):\n",
|
||||||
|
" def __init__(self, an_arg):\n",
|
||||||
|
" print('excecuted __init__')\n",
|
||||||
|
" self.an_arg = an_arg\n",
|
||||||
|
" \n",
|
||||||
|
"a_object = a_class(1)\n",
|
||||||
|
"print('Type of a_object:', type(a_object))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"excecuted __init__\n",
|
||||||
|
"Type of a_object <class '__main__.a_class'>\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 24
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
|
@ -3128,23 +3414,17 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
|
"#### 05/02/2014\n",
|
||||||
|
"- new section: Metaclasses - What creates a new instance of a class? \n",
|
||||||
|
"\n",
|
||||||
"#### 05/01/2014\n",
|
"#### 05/01/2014\n",
|
||||||
"- new section: keyword argument unpacking syntax\n",
|
"- new section: keyword argument unpacking syntax\n",
|
||||||
"\n",
|
"\n",
|
||||||
"#### 04/27/2014\n",
|
"#### 04/27/2014\n",
|
||||||
"- minor fixes of typos\n",
|
"- minor fixes of typos \n",
|
||||||
"- single- vs. double-underscore clarification in the private class section."
|
"- new section: \"Only the first clause of generators is evaluated immediately\""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"collapsed": false,
|
|
||||||
"input": [],
|
|
||||||
"language": "python",
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"prompt_number": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "",
|
"name": "",
|
||||||
"signature": "sha256:80251f5a867d952a8908417662c4e9a63acad3a148fcbcd67d9a19345eb1828f"
|
"signature": "sha256:8d4ed5310005c7fea9f7cfda8b7624b8b3cb390a566950a3bc179c516f89b410"
|
||||||
},
|
},
|
||||||
"nbformat": 3,
|
"nbformat": 3,
|
||||||
"nbformat_minor": 0,
|
"nbformat_minor": 0,
|
||||||
|
@ -82,7 +82,8 @@
|
||||||
"- [Abortive statements in `finally` blocks](#finally_blocks)\n",
|
"- [Abortive statements in `finally` blocks](#finally_blocks)\n",
|
||||||
"- [Assigning types to variables as values](#variable_types)\n",
|
"- [Assigning types to variables as values](#variable_types)\n",
|
||||||
"- [Only the first clause of generators is evaluated immediately](#generator_rhs)\n",
|
"- [Only the first clause of generators is evaluated immediately](#generator_rhs)\n",
|
||||||
"- [Keyword argument unpacking syntax - `*args` and `**kwargs`](#splat_op)"
|
"- [Keyword argument unpacking syntax - `*args` and `**kwargs`](#splat_op)\n",
|
||||||
|
"- [Metaclasses - What creates a new instance of a class?](#new_instance)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3002,6 +3003,13 @@
|
||||||
"# Only the first clause of generators is evaluated immediately"
|
"# Only the first clause of generators is evaluated immediately"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"[[back to top](#sections)]"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -3098,6 +3106,13 @@
|
||||||
"##Keyword argument unpacking syntax - `*args` and `**kwargs`"
|
"##Keyword argument unpacking syntax - `*args` and `**kwargs`"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"[[back to top](#sections)]"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -3201,6 +3216,105 @@
|
||||||
],
|
],
|
||||||
"prompt_number": 3
|
"prompt_number": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a name=\"new_instance\"></a>\n",
|
||||||
|
"<br>\n",
|
||||||
|
"<br>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Metaclasses - What creates a new instance of a class?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Usually, it is the `__init__` method when we think of instanciating a new object from a class. However, it is the static method `__new__` (it is not a class method!) that creates and returns a new instance before `__init__()` is called. \n",
|
||||||
|
"More specifically, this is what is returned: \n",
|
||||||
|
"`return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)` \n",
|
||||||
|
"\n",
|
||||||
|
"For more information about the `__new__` method, please see the [documentation](https://www.python.org/download/releases/2.2/descrintro/#__new__).\n",
|
||||||
|
"\n",
|
||||||
|
"As a little experiment, let us screw with `__new__` so that it returns `None` and see if `__init__` will be executed:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"class a_class(object):\n",
|
||||||
|
" def __new__(clss, *args, **kwargs):\n",
|
||||||
|
" print('excecuted __new__')\n",
|
||||||
|
" return None\n",
|
||||||
|
" def __init__(self, an_arg):\n",
|
||||||
|
" print('excecuted __init__')\n",
|
||||||
|
" self.an_arg = an_arg\n",
|
||||||
|
" \n",
|
||||||
|
"a_object = a_class(1)\n",
|
||||||
|
"print('Type of a_object:', type(a_object))"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"excecuted __new__\n",
|
||||||
|
"Type of a_object: <class 'NoneType'>\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"As we can see in the code above, `__init__` requires the returned instance from `__new__` in order to called. So, here we just created a `NoneType` object. \n",
|
||||||
|
"Let us override the `__new__`, now and let us confirm that `__init__` is called now to instantiate the new object\":"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"class a_class(object):\n",
|
||||||
|
" def __new__(cls, *args, **kwargs):\n",
|
||||||
|
" print('excecuted __new__')\n",
|
||||||
|
" inst = super(a_class, cls).__new__(cls)\n",
|
||||||
|
" return inst\n",
|
||||||
|
" def __init__(self, an_arg):\n",
|
||||||
|
" print('excecuted __init__')\n",
|
||||||
|
" self.an_arg = an_arg\n",
|
||||||
|
" \n",
|
||||||
|
"a_object = a_class(1)\n",
|
||||||
|
"print('Type of a_object:', type(a_object))\n",
|
||||||
|
"print('a_object.an_arg: ', a_object.an_arg)"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"excecuted __new__\n",
|
||||||
|
"excecuted __init__\n",
|
||||||
|
"Type of a_object: <class '__main__.a_class'>\n",
|
||||||
|
"a_object.an_arg: 1\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 54
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -3230,6 +3344,9 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
|
"#### 05/02/2014\n",
|
||||||
|
"- new section: Metaclasses - What creates a new instance of a class? \n",
|
||||||
|
"\n",
|
||||||
"#### 05/01/2014\n",
|
"#### 05/01/2014\n",
|
||||||
"- new section: keyword argument unpacking syntax\n",
|
"- new section: keyword argument unpacking syntax\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user