dave wrote:

class transmit_path(gr.top_block)
[...]
        self.packet_transmitter = ieee802_15_4_pkt.ieee802_15_4_mod_pkts(self,
                                  spb=self._spb, msgq_limit=2)


This calls the ieee802_15_4_mod_pkts initializer (not a constructor -- see below) with one positional argument and two keyword arguments.

The positional argument is "self", that is, the transmit_path instance.

The keyword arguments are called spb and msgq_limit; spb is set to the value of self._spb, and msgq_limit is set to 2.

The reason I say this is an initializer and not a constructor is that Python treats the two as different. The constructor that creates the instance is called __new__ not __init__. When __init__ is called, the instance has already been constructed, and is now being initialized. The reason for this is mostly historical, although it is useful.

(Disclaimer -- so called "old style" or "classic" classes don't have a __new__ method, and you cannot customize the actual creation of the instance, only the initialization.)

Looking at the ieee802_15_4_mod_pkts initializer:


class ieee802_15_4_mod_pkts(gr.hier_block2):
    def __init__(self, pad_for_usrp=True, *args, **kwargs):[/code]

As a method, this takes the instance as first argument (called "self"), plus one named argument "pad_for_usrp", an arbitrary number of unnamed positional arguments collected into "args", and an arbitrary number of named keyword arguments collected into "kwargs".

(Note that args and kwargs are conventions. You could call them anything you like -- the "magic", so to speak, comes from the leading * and ** and not from the names.)

Given the call:

ieee802_15_4_mod_pkts(self, spb=self._spb, msgq_limit=2)

this corresponds to the initializer receiving arguments:

self = the freshly created ieee802_15_4_mod_pkts instance
pad_for_usrp = the transmit_path instance doing the calling
args = an empty tuple (no positional arguments collect)
kwargs = a dictionary of keyword arguments
         {'spb': value of _spb of the transmit_path instance,
          'msgq_limit': 2}


What I don't understand is the call to the constructor and the constructor
definition.  Since it's using a number of advanced features, I'm having
trouble looking it all up in documentation.

What does it mean to call with spb=self._spb?  In the example file, spb is set
= to 2 and so is self._spb.  Is it a sort of pass by reference like C while
also assigning a value? Why the  ** on kwargs then? as if it is a matrix

No, this is nothing to do with pass by reference, or pass by value either. This often confuses people coming to Python from some other languages, and if it isn't a FAQ it ought to be. You can read one of my posts on this here:

http://www.mail-archive.com/tutor%40python.org/msg46612.html

and the Wikipedia article:

http://en.wikipedia.org/wiki/Evaluation_strategy


What it means is that the method being called (in this case, ieee802_15_4_mod_pkts.__init__) sees a keyword argument called "spb". This keyword argument has name "spb", and value whatever self._spb has at the time it is called.

When Python allocates arguments to the named parameters in a method or function, its basic process is roughly something like this:


(1) for methods, automatically assign the instance being called to the first named parameter (usually called "self" by convention);

(2) take each positional argument from the caller and assign it to the remaining positional parameters, from left to right;

(3) assign any keyword arguments, raising an error if it duplicates a value already seen;

(4) raise an error if any unassigned parameter doesn't have a default value;

(5) collect any left over positional arguments into the *args parameter;

(6) collect any left over keyword arguments into the **kwargs parameter.



(and does anyone have any idea what kwargs are (as opposed to args)?)


Positional arguments: function(1, 2)
Keyword arguments: function(a=1, b=2)



I'm uncertain about the first argument, but I guess it must be the
transmit_path object passed in place of the usually implicit self...  I'm just
not sure how Python figures out that it's not pad_for_usrp... magic I guess!

I don't think that it is used as the implicit self. I think it is the pad_for_usrp.




--
Steven

_______________________________________________
Tutor maillist  -  [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to