Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is no way to detect how the returned attribute was intended to be used. <em>Everything</em> on python objects are attributes, including the methods:</p> <pre><code>&gt;&gt;&gt; class Foo(object): ... def bar(self): print 'bar called' ... spam='eggs' ... &gt;&gt;&gt; Foo.bar &lt;unbound method Foo.bar&gt; &gt;&gt;&gt; Foo.spam 'eggs' </code></pre> <p>Python first looks up the attribute (<code>bar</code> or <code>spam</code>), and if you meant to <em>call</em> it (added parenthesis) then Python invokes the callable <em>after</em> lookup up the attribute:</p> <pre><code>&gt;&gt;&gt; foo = Foo() &gt;&gt;&gt; fbar = foo.bar &gt;&gt;&gt; fbar() 'bar called' </code></pre> <p>In the above code I separated the lookup of <code>bar</code> from calling <code>bar</code>.</p> <p>Since there is no distinction, you cannot detect in <code>__getattr__</code> what the returned attribute will be used for.</p> <p><code>__getattr__</code> is called whenever normal attribute access fails; in the following example <code>monty</code> is defined on the class, so <code>__getattr__</code> is <em>not</em> called; it is only called for <code>bar.eric</code> and <code>bar.john</code>:</p> <pre><code>&gt;&gt;&gt; class Bar(object): ... monty = 'python' ... def __getattr__(self, name): ... print 'Attribute access for {0}'.format(name) ... if name == 'eric': ... return 'idle' ... raise AttributeError(name) ... &gt;&gt;&gt; bar = Bar() &gt;&gt;&gt; bar.monty 'python' &gt;&gt;&gt; bar.eric Attribute access for eric 'idle' &gt;&gt;&gt; bar.john Attribute access for john Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; File "&lt;stdin&gt;", line 7, in __getattr__ AttributeError: john </code></pre> <p>Note that functions are not the only objects that you can invoke (call); any custom class that implements the <code>__call__</code> method will do:</p> <pre><code>&gt;&gt;&gt; class Baz(object): ... def __call__(self, name): ... print 'Baz sez: "Hello {0}!"'.format(name) ... &gt;&gt;&gt; baz = Baz() &gt;&gt;&gt; baz('John Cleese') Baz sez: "Hello John Cleese!" </code></pre> <p>You could use that return objects from <code>__getattr__</code> that can both be called and used as a value in different contexts.</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. This table or related slice is empty.
    1. 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