On Mon, 4 Jul 2016 09:23 pm, jmp wrote: > On 07/01/2016 04:13 PM, Steven D'Aprano wrote: >> But classes are not like the others: they must be instantiated before >> they can be used, and they are more than just a mere namespace grouping >> related entities. Classes support inheritance. Classes should be used for >> "is-a" relationships, not "has-a" relationships. Although classes (and >> instances) are namespaces, they provide fundamentally different kind of >> behaviour than modules and packages. > > A namespace would not hurt but I really don't get why you don't consider > classes a valid and rather helpful namespace.
I never said that. This is where the term "namespace" can be ambiguous. "Namespace" can refer to any of: - an abstract mapping of symbols (names) to values; - specific kinds of namespaces: * the concrete C++/C#/PHP data type called "namespace"; * Python packages and modules; * classes; * instances of a class; - the implementation (the __dict__ attribute of modules, classes); etc. Now clearly a class is not the same thing as the class __dict__, and a module is not the same as a class, and neither modules nor classes are the same as a C++ namespace. Doesn't mean that classes aren't valid namespaces, just that their semantics, use-cases and behaviour are different to those of modules. > 1/ classes do not have to be instantiated. That's a bit of a sore point to me. Some years ago I wrote here to ask what name is given to a class that is not instantiated before being used. Singleton classes get instantiated once, allowing a single instance. What if you had a class that didn't need instantiating at all, so that the class itself was *effectively* the singleton? What should that be called? Instead of this: class SingletonClass: ... singleton = SingletonClass() singleton.method() what if we had this instead? class singleton: ... singleton.method() I was roundly told that this was crazy talk, that the whole point of classes was that they must be instantiated to use them, that code like the second example would be confusing and very possibly bring about the fall of Western Civilisation. The idea that this might be a legitimate alternative to the singleton design pattern was dismissed. (The Python community is terribly conservative when it comes to code.) And, in a sense, they were right: there are two common ways to get singleton-like behaviour in general, and in Python specifically: - use class that allows only a single instance; - use a module. Using the class itself is unusual and surprising (especially to Java programmers, where classes aren't even first-class values), and more so, it's *inconvenient*. To write a class which is used without instantiation, you should raise an error on instantiation, decorate every method using classmethod or staticmethod, and have methods have to call each other using the dotted name: class Example: var = 999 def __init__(self): raise TypeError('do not instantiate this class') @classmethod def spam(cls, arg): return cls.eggs(arg) + cls.var @classmethod def eggs(cls, arg): return arg*2 *** IF *** you are willing to push the code out into its own separate .py file, you can use a module and write your code in a more natural form: # module example.py var = 999 def spam(arg): return eggs(arg) + var def eggs(arg): return arg*2 What I'm calling a "namespace" is just a module object that lives inside another module, without requiring a separate .py file. It only uses the "class" statement for pragmatic reasons: there's no other statement available that will do the job. > 2/ the fact that classes are more than a namespace is not an argument. > Almost any object in python is able to do more than what you are > actually using. There's one aspect of classes that is a deliberate design feature, but goes against what I'm after: the fact that the class namespace itself is NOT part of the method name resolution rules (except during class construction). Try this: x = 999 class Example: x = 1 print(x) # called during class construction @classmethod def test(cls): print(x) Example.test() This will print 1, then 999. We quite often get people complaining about this. I'm not one of them. I want classes to keep the current rules. But it shows that a class is not the right answer for a module-inside-a-module object. > 3/ Classes are used as much as 'is-a' than 'has-a', class instances > *have* a state usually described by attributes Instances have state, of course, but the relationship I'm talking about is instance to class. class Dog: ... lassie = Dog() Lassie is a dog, not "Lassie has a dog". Lassie has a tail, not "Lassie is a tail". That's why we have IS_instance and HAS_attr builtins. The expectation is that a class represents a model of a physical kind of thing, whether that's a Dog or a HTTPServer or a float. If you want a collection of related functions, classes and variables, put them in a different kind of namespace, namely a module (if using a separate .py file is okay) or a Namespace. -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list