diff --git a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb index 848d37c..9c32267 100644 --- a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb +++ b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:92f953fd8004f1dd1e9969ce61096f5a0b43190de3f3c7c8f85642b667754fae" + "signature": "sha256:70671a8e3f32d21b27867ecdc6d80f3b5c10f00339a2fae3860c4db8930dc7c6" }, "nbformat": 3, "nbformat_minor": 0, @@ -13,7 +13,7 @@ "metadata": {}, "source": [ "Sebastian Raschka \n", - "last updated: 04/27/2014 ([Changelog](#changelog))\n", + "last updated: 05/02/2014 ([Changelog](#changelog))\n", "\n", "[Link to this IPython Notebook on GitHub](https://github.com/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb)\n", "\n", @@ -3151,7 +3151,7 @@ ] } ], - "prompt_number": 1 + "prompt_number": 55 }, { "cell_type": "markdown", @@ -3179,12 +3179,12 @@ "stream": "stdout", "text": [ "type of kwargs: \n", - "kwargs contents: {'b': 2, 'a': 1, 'c': 3, 'd': 4}\n", + "kwargs contents: {'d': 4, 'a': 1, 'c': 3, 'b': 2}\n", "value of argument a: 1\n" ] } ], - "prompt_number": 2 + "prompt_number": 56 }, { "cell_type": "markdown", @@ -3214,7 +3214,7 @@ ] } ], - "prompt_number": 3 + "prompt_number": 57 }, { "cell_type": "markdown", @@ -3237,69 +3237,14 @@ "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(, 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", - "`__new__` is a so-called static method that returns \n", - "`return super(, cls).__new__(subcls, *args, **kwargs)`" + "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": [ - "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, @@ -3327,22 +3272,32 @@ ] } ], - "prompt_number": 33 + "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__(clss, *args, **kwargs):\n", + " def __new__(cls, *args, **kwargs):\n", " print('excecuted __new__')\n", - " inst = super(a_class, clss).__new__(clss, *args, **kwargs)\n", + " inst = super(a_class, cls).__new__(cls)\n", " return inst\n", - " def __init__(self):\n", + " def __init__(self, an_arg):\n", " print('excecuted __init__')\n", + " self.an_arg = an_arg\n", " \n", - "a_object = a_class()\n", - "print('Type of a_object:', type(a_object))" + "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": {}, @@ -3353,37 +3308,12 @@ "text": [ "excecuted __new__\n", "excecuted __init__\n", - "Type of a_object: \n" + "Type of a_object: \n", + "a_object.an_arg: 1\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 \n" - ] - } - ], - "prompt_number": 24 + "prompt_number": 54 }, { "cell_type": "markdown", @@ -3424,14 +3354,6 @@ "- minor fixes of typos \n", "- new section: \"Only the first clause of generators is evaluated immediately\"" ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] } ], "metadata": {} diff --git a/not_so_obvious_python_stuff.ipynb b/not_so_obvious_python_stuff.ipynb index ced0fb1..9c32267 100644 --- a/not_so_obvious_python_stuff.ipynb +++ b/not_so_obvious_python_stuff.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:8d4ed5310005c7fea9f7cfda8b7624b8b3cb390a566950a3bc179c516f89b410" + "signature": "sha256:70671a8e3f32d21b27867ecdc6d80f3b5c10f00339a2fae3860c4db8930dc7c6" }, "nbformat": 3, "nbformat_minor": 0, @@ -13,7 +13,7 @@ "metadata": {}, "source": [ "Sebastian Raschka \n", - "last updated: 04/27/2014 ([Changelog](#changelog))\n", + "last updated: 05/02/2014 ([Changelog](#changelog))\n", "\n", "[Link to this IPython Notebook on GitHub](https://github.com/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb)\n", "\n", @@ -3151,7 +3151,7 @@ ] } ], - "prompt_number": 1 + "prompt_number": 55 }, { "cell_type": "markdown", @@ -3179,12 +3179,12 @@ "stream": "stdout", "text": [ "type of kwargs: \n", - "kwargs contents: {'b': 2, 'a': 1, 'c': 3, 'd': 4}\n", + "kwargs contents: {'d': 4, 'a': 1, 'c': 3, 'b': 2}\n", "value of argument a: 1\n" ] } ], - "prompt_number": 2 + "prompt_number": 56 }, { "cell_type": "markdown", @@ -3214,7 +3214,7 @@ ] } ], - "prompt_number": 3 + "prompt_number": 57 }, { "cell_type": "markdown", @@ -3354,14 +3354,6 @@ "- minor fixes of typos \n", "- new section: \"Only the first clause of generators is evaluated immediately\"" ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] } ], "metadata": {}