Mike McClain <mike.junk...@att.net> writes: > ... > Thanks for the response, this is still a foreign language to me and I > need all > the help I can get. I'm reading the docs, doing the tutorial again but > still have > more questions than answers. > If I understand what you said, 'taint necessarily so, I'll restate it > in psuedo > code since I've little feel for python syntax yet. > > Let's forget buz(). > > def bar(*args): > (a,b,rest) = parseArgs(args) > def baz(x): > ... > def bug(k,l,m): > ... > bug(foo(a), baz(b), rest) > > In 'def bar()', baz & bug are simply functions.
Indeed. > Are they accessable outside bar? No, unless they are explicitly passed out by "bar" (usually either as function result or part thereof; but there are other ways as well). > class bar(*args): > (a,b,rest) = parseArgs(args) I do not think that this would work. While the "class" statement (defining a class) has some similarity with the "def" statement (defining a function), there are also differences. In particular, the arguments in "class C(<arguments>)" correspond to arguments passed to a function call, not the arguments of a function definition. As one consequence, they are not made visible in the class' namespace: your "parseArgs(args)" above will not work (likely, you will already get an error before that point. As a side note: Associated with a class definition is a so called "metaclass" (the association is usually implicit, but can be made explicit). The arguments in "class C(<arguments>)" are passed as one of the parameters in a metaclass call (other parameters are the class name and the class dict). Thus, the "class" statement effectively leads to a (function/method) call with the somewhat prepared content of the class statement as parameters. > def baz(x): > ... > ... > > In 'class bar()' I understand baz and bug should be named _baz_ , _bug_, > if they're not expected to be called from outside bar but there's nothing > to prevent one from doing so except manners. It is a tacit convention that names starting with a "_" are in various ways special: __...__: are usually used for Python internal purposes and often treated very differently from other attributes. Usually, you should avoid to define such attributes yourself, unless you want to customize the associated Python behaviour. Otherwise, future Python versions might give a special meaning to your attribute and it may then no longer work as in previous Python versions. __...: those attributes are mangled inside a class statement: the mangling consists of prepending "_<class name>". The purpose of this feature is to avoid name clashes in class inheritance. "__..." attribute are in some way "private" to the class (as far as the mangling ensures this), not (easily) seen be deriving classes. _...: provides a hint that this attribute/name is ment more for "local" rather then "public" use. There is nothing in Python that enforces this. > Also they're now methods while > still being functions and had to be declared 'def baz(self,x):'. The precise details are as follows: The "def" always defines a function (whether or not it appears inside or outside of a "class" statement). If used inside a "class" statement, the function is put into the dictionary associated with the constructed class. If an attribute of a class or class instance is looked up in the "normal" way" (i.e. "<obj>.<attr>") and the result happens to be a function, then the function is not returned directly but wrapped into a method wrapper (containing both "<obj>" and the function). This means that the function is turned into a method during its access (not during its definition). Usually, you access the functions in a "class" definition in the "normal way" - and the result will behave as a method. Thus, you can view (for simplicity) the corresponding definitions as method definitions -- even though the transformation into a method only happens on access to (and not on definition of) the function. > Feel free to laugh if what I'm saying is nonsense in python. Do not be worried. > If I execute 'bar.baz(mu)', As mentioned above, your example will not work. Let's modify a bit: class C: def baz(self, b): ... c = C() If you use "C.baz", the result is in Python 2 a so called "unbound method": it contains the class "C" and the function "baz". If you want to call an "unbound method", you must pass in all function arguments, including the first one. The call will raise a "TypeError", when the first argument is not an instance of the associated class. In Python 3, "C.baz" returns the function "baz". If you use "c.baz", the result is a so called "bound method": it contains the object "c" and the function "baz". If you call a "bound method", the associated object is passed autemoatically as first parameter to the function; you specify only the remaining arguments in the call. > assuming mu is enough like b above for > baz not to throw an exception, can I expect the action of baz to change > in a > manner similar to the change in parameters? Or does something in self > prevent that? I do not understand your question and expectations. Hopefully, my explanation above will already clarify Python's treatment of functions versus methods sufficiently, that you can understand what is happening or at least that you can reformulate your question. As a side note: you can fairly safely play with Python in an interactive way - and thus learn much about Python internals. Below is a transcript for the exploration of the function/method handling discussed in the message: lsdm: python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux >>> class C: ... def baz(self, b): print(b) ... >>> c = C() >>> C.baz <function C.baz at 0xb712c7c4> >>> C.baz(1,2) 2 >>> c.baz <bound method C.baz of <__main__.C object at 0xb70311ac>> >>> c.baz(2) 2 # provide information about the method's attributes >>> dir(c.baz) ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] # "<method>.__self__" contains the associated object >>> c.baz.__self__ is c True # "<method>.__func__" contains the associated function >>> c.baz.__func__ is C.baz True -- https://mail.python.org/mailman/listinfo/python-list