Classes - converting external function to class's method.

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Dec 14 21:01:02 EST 2014


Thomas 'PointedEars' Lahn wrote:

> Ivan Evstegneev wrote:
> 
>> I have stuck a bit with this example(took this one from the book).
>> 
>> Here are a description steps of what I've done till now:
>>  
>> 
>> Step 1 - creating an empty namespace:
>> 
>>>>>class rec: pass
> 
> IMHO that is not actually creating a namespace; it is just
> declaring/defining an empty class.

And classes are namespaces. As are instances.

One clue is the fact that we use exactly the same syntax for accessing names
in a namespace regardless of whether the namespace is a package, a module,
a class or an instance:

import collections.abc  # a package namespace
math.sin  # a module namespace
OrderedDict.fromkeys  # a class namespace
mystring.upper  # an instance namespace

I call it a "clue" rather than definitive proof because the syntax is not
quite the same for all namespaces. Local and global variables also exist in
namespaces, but you don't use dotted notation for them.

Another clue is that most of these are implemented by using a __dict__ to
store the name:value mapping. Again, that's not universal: instances can
optionally use __slots__ instead of __dict__ and packages use the file
system.

Apart from packages, one can use getattr(), setattr() and delattr() on all
of these objects (modules, classes and instances) to manipulate their
attributes.

Wikipedia says:

"In general, a namespace is a container for a set of identifiers (also known
as symbols, names)."

https://en.wikipedia.org/wiki/Namespace

and that applies to packages, modules, classes, and instances.

Last but not least, another clue: in some languages, such as Java, what
Python calls "attributes" are known as *variables*. So per-instance members
are called "instance variables", per-class members are sometimes
called "class variables" (although not in Java, where I believe they are
known as static variables for technical reasons). Personally, I don't like
that terminology, but I do recognise that it does reflect a certain
connection between names in local/global/instance/class namespaces.


> BTW, the recommended Python 3.x way is
> 
> class Rec (object):
>     pass


I think you mean Python 2 rather than 3. In Python 2, we have legacy "old
style" or "classic" classes, and "new style" classes which inherit from
object. In Python 3, classic classes are gone, and inheriting from object
is optional.


> (whereas “pass” is a placeholder statement, a bit like the yada-yada
> operator of Python) and you should start class identifiers uppercase
> (therefore, “Rec” instead) in order to avoid name collisions with built-in
> class identifiers (“str”, “int” etc.) and make it easier to tell apart
> instantiations from function/method calls.

Agreed!

It is good practice to name classes with initial capital letter, and
instances in all lowercase.


> If you call that method as the method of a class (object), you need to
> pass an argument for the first parameter because you have made it
> positional, not
> optional (it has no default value).  If you pass (a reference to) the
> class as first argument of that method, the class is the object whose
> attribute is
> accessed.  Classes are objects (this, too, was probably derived from
> Java). (In fact, AFAIK almost everything is an object in Python; there are
> no primitive data types at all.)

You are correct that "everything is an object" in Python, but wrong that
this is derived from Java. As I understand it, Java classes are not values:
you cannot assign a class to a variable, or create classes on the fly, or
delete them, or stick them in lists, etc. 

Well, I say that you can't do it, but you actually can, using reflection and
other tricks. But the important thing is that you need to use special
techniques to work around the fact that classes aren't values and therefore
not implemented as objects in Java. What is natural in Python is unnatural
in Java.

http://stackoverflow.com/questions/2320404/creating-classes-dynamically-with-java


[...]
> If you intend the function to be called as the method of an instance, you
> would be well-advised to name the parameter “self”, as recommended. 
> (Which is probably derived from Smalltalk-80 and Self, some of the first
> OOPLs.)

Good advice.


-- 
Steven




More information about the Python-list mailing list