Use of Parameter and Signature
<p>I am a relatively new Python learner. So, while going through different coding techniques, I came across this:</p>

<pre><code>from inspect import Parameter, Signature

def make_signature(names):
    return Signature(Parameter(name, Parameter.POSITIONAL_OR_KEYWORD) for name in names)

class Structure:
    list_fields = []
    def __init__(self, *args):
        for name, val in zip(self.list_fields, args):
            setattr(self, name, val)

class Stock(Structure):
    __signature__ = make_signature(['name', 'shares', 'price'])
    #list_fields = ['name', 'shares', 'price'] 

class Point(Structure):
    list_fields = ['x', 'y']

obj2=Point(20,40)
obj1=Stock('googl', 100, 8000)
print(obj1.name)
</code></pre>

<p>I understand the <code>Structure</code> class and its integration with the <code>Point</code> class which is inheriting <code>Structure</code> class hence it's <code>__init__</code> method. But when I create object of <code>Point</code> class it doesn't support <strong>Positional arguments</strong> but the <code>Stock</code> class object does support the feature.</p>

<ul>
<li>Can anyone please explain to me why &amp; how this happens?</li>
<li>When to use Parameter, Signature?</li>
<li>Also how is this related to meta programming?</li>
<li>Some more examples like this.</li>
<li>what is the use of <code>Parameter</code> function in <code>make_signature</code> method and what <code>make_signature</code> method is doing?</li>
<li>The flow of the program i.e which function is returning to whom and vice-versa. To my knowledge the <code>Stock</code> class and <code>Point</code> class are calling the <code>Structure</code> class but when does the <code>make_signature</code> method comes in?</li>
</ul>

<p>And I tried to read some documentation about <code>Signature</code> but those examples aren't of this kind and is too much heavy stuff for me as I keep getting lost backtracking this code documentations also I couldn't find any good explanatory documentation on Meta programming in Python.</p>

<blockquote>
  <p>Can anyone please explain to me why &amp; how this happens?</p>
</blockquote>

<p>Both classes <em>only</em> accept positional arguments as dictated by <code>*args</code> in <code>Structure.__init__</code>:</p>

<pre><code>s = Stock('pos_arg1', 'pos_arg2', 'pos_arg3')
p = Point('pos_arg1', 'pos_arg2', 'pos_arg3')
</code></pre>

<p>The difference is that <code>Stock</code> doesn't actually <em>set</em> any arguments because, since you commented out <code>list_fields</code>, <code>Structure.__init__</code> will use <code>Structure.list_fields</code> which is empty. That is why trying to access <code>name</code> on a <code>Stock</code> instance raises an <code>AttributeError</code>.</p>

<p>In both cases, <code>list_fields</code> <strong>limits</strong> what arguments can be set. For the <code>Point</code> instance in the previous snippet, <code>x</code> will equal <code>pos_arg1</code> and <code>y</code> will equal <code>pos_arg2</code>; <code>pos_arg3</code> is essentially tossed. This is due to <code>zip</code> which builds tuples until one of the iterables is exhausted:</p>

<pre><code>for i, j in zip(['x', 'y'], ['pos_arg1', 'pos_arg2', 'pos_arg3']):
    print(i, j)
</code></pre>

<p>Prints:</p>

<pre><code>x pos_arg1
y pos_arg2
</code></pre>

<p>When an empty list is supplied, it doesn't even loop. This is what happens when you initialize <code>Stock</code>, <code>Structure.list_fields = []</code> is used:</p>

<pre><code>for i, j in zip([], ['pos_arg1', 'pos_arg2', 'pos_arg3']):
    print(i, j)
</code></pre>

<p>Prints nothing so no <code>setattr</code>s are going to get called.</p>

<blockquote>
  <p>When to use Parameter, Signature?</p>
</blockquote>

<p>When you want to support further introspection of your classes (or, callables in the general case) you could add a <code>__signature__</code> attribute to your class (as is done with <code>Stock</code>) and get it picked up by tools like <code>inspect.signature</code>, i.e:</p>

<pre><code>inspect.signature(Stock)
Out[16]: &lt;Signature (name, shares, price)&gt;

inspect.signature(Point)
Out[17]: &lt;Signature (*args)&gt;
</code></pre>

<p>Signature tries to see if the object has a <code>object.__signature__</code> and if so constructs a representation of the signature when called.</p>

<p>Furthermore you could <code>bind</code> a signature to self and get it to support <code>POSITIONAL_OR_KEYWORD</code> arguments.</p>

<p>In general this will only present itself as requirement in very few cases. In short: you'll know if you'll need it. </p>

<blockquote>
  <p>Also how is this related to meta programming? </p>
</blockquote>

<p>This specific example isn't related. You could enhance it with meta programming as you'll see in the presentation I'll link.</p>

<blockquote>
  <p>Some more examples like this.</p>
</blockquote>

<p>This is too broad of a request. But your example comes from david beazly's metaprogramming presentation, <a href="http://pyvideo.org/pycon-us-2013/python-3-metaprogramming.html" rel="nofollow">here's the presentation</a>.</p>

<blockquote>
  <p>To my knowledge Stock function and Point function is calling Structure class but where does the make_signature method comes in?</p>
</blockquote>

<p>Both <code>Stock</code> and <code>Point</code> use <code>Structure.__init__</code> which will populate the instance dictionary with attributes defined in <code>list_fields</code>. </p>

<p><code>__signature__ = make_signature([...])</code> is executing <em>when the class is being created</em>, Python executes the body of the <code>class</code> when it encounters it. <code>make_signature</code> is going to get called and create a <code>Signature</code> object and the assignment to <code>__signature__</code> is going to be made.</p>

python python-3.x metaprogramming