Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In Python, there is a difference between functions and bound methods.</p> <pre><code>&gt;&gt;&gt; def foo(): ... print "foo" ... &gt;&gt;&gt; class A: ... def bar( self ): ... print "bar" ... &gt;&gt;&gt; a = A() &gt;&gt;&gt; foo &lt;function foo at 0x00A98D70&gt; &gt;&gt;&gt; a.bar &lt;bound method A.bar of &lt;__main__.A instance at 0x00A9BC88&gt;&gt; &gt;&gt;&gt; </code></pre> <p>Bound methods have been "bound" (how descriptive) to an instance, and that instance will be passed as the first argument whenever the method is called.</p> <p>Callables that are attributes of a class (as opposed to an instance) are still unbound, though, so you can modify the class definition whenever you want:</p> <pre><code>&gt;&gt;&gt; def fooFighters( self ): ... print "fooFighters" ... &gt;&gt;&gt; A.fooFighters = fooFighters &gt;&gt;&gt; a2 = A() &gt;&gt;&gt; a2.fooFighters &lt;bound method A.fooFighters of &lt;__main__.A instance at 0x00A9BEB8&gt;&gt; &gt;&gt;&gt; a2.fooFighters() fooFighters </code></pre> <p>Previously defined instances are updated as well (as long as they haven't overridden the attribute themselves):</p> <pre><code>&gt;&gt;&gt; a.fooFighters() fooFighters </code></pre> <p>The problem comes when you want to attach a method to a single instance:</p> <pre><code>&gt;&gt;&gt; def barFighters( self ): ... print "barFighters" ... &gt;&gt;&gt; a.barFighters = barFighters &gt;&gt;&gt; a.barFighters() Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; TypeError: barFighters() takes exactly 1 argument (0 given) </code></pre> <p>The function is not automatically bound when it's attached directly to an instance:</p> <pre><code>&gt;&gt;&gt; a.barFighters &lt;function barFighters at 0x00A98EF0&gt; </code></pre> <p>To bind it, we can use the <a href="http://docs.python.org/library/types.html?highlight=methodtype#module-types" rel="noreferrer">MethodType function in the types module</a>:</p> <pre><code>&gt;&gt;&gt; import types &gt;&gt;&gt; a.barFighters = types.MethodType( barFighters, a ) &gt;&gt;&gt; a.barFighters &lt;bound method ?.barFighters of &lt;__main__.A instance at 0x00A9BC88&gt;&gt; &gt;&gt;&gt; a.barFighters() barFighters </code></pre> <p>This time other instances of the class have not been affected:</p> <pre><code>&gt;&gt;&gt; a2.barFighters() Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; AttributeError: A instance has no attribute 'barFighters' </code></pre> <p>More information can be found by reading about <a href="http://users.rcn.com/python/download/Descriptor.htm" rel="noreferrer">descriptors</a> and <a href="http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html" rel="noreferrer">metaclass</a> <a href="http://www.gnosis.cx/publish/programming/metaclass_2.html" rel="noreferrer">programming</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload