I'm trying to learn how to make GUI with Traits. I'm new in object oriented programming and I'm new in Python. Most of the examples I could find on the net do not use any constructor in the Hastraits subclass. Should I forget about the def init(self, *arg) constructor? Or should I force myself to use it ?
For example, taking the example from :
Change property parameter from within class constructor [Python / Traits]
the code from DrSAR is to me the most simple and elegant of all the examples; and yet it doesn't use constructor. Did I miss something?
Short answer: no, don't write __init__() initializers when subclassing from HasTraits.
The HasTraits class defines a generic and very flexible __init__() that takes the keyword arguments given to it and assigns the values to the corresponding attributes. Your subclass will inherit this initializer. Given that the trait definitions usually provide sensible defaults for each attribute, there is usually no reason to need another initializer. There are cases where one does want to override this initializer, but they are relatively rare. I might only do so once every 100 or so classes that I write.
If you wanted practice writing initializers for standard subclassing-from-object Python, sorry. Traits has its own set of conventions and best practices that you will be learning in addition to the general OO and Python principles; some of the former will moot the latter.
Related
Functions in a python class can be either instance methods, class methods or static methods.
The former is characterised by the self as its first (implicit) argument, acts directly on the instance of the class, and does not require any decorators to be treated as such.
The other two, however, need decorators #classmethod and #staticmethod before the name of the method - this is why I refer to the instance method as the "default" one, i.e. the one for which a wrapper is not needed.
My question is: suppose I am in a class, and I am breaking up my calculation into several functions for readibility. Only one of these methods will need access to the self.something variables that I share instance-wise, but most of the others do not need to know about the class they belong to - they are just there for "housekeeping".
Should make these functions (the ones that do not need any self.something knowledge) all #staticmethod? Doing so would require a decorator and hence an extra step. It would be easier (not requiring the extra step of using a decotrator) for every method to just be an instance method, thus inheritig a lot of potential but also waisting it since it is not needed for the scope of the functions in question.
Why is the instance method the "default"? Why not have every method a static method by default, and give it the extra functionality associated with being a instance method with a wrapper?
The reason to default to instance methods is because that's usually what you want when you're doing object oriented programming. I can't think of a single language that claims to support OOP and has methods default to anything but instance methods. Classes are templates for "data with behaviors", so the default is to make methods that provide behaviors to each instantiation of the class. If you just want a collection of functions, you can just define them at the top level of a module and save the unnecessary class after all.
In general, #staticmethod is used to mean "I know this isn't a behavior of the class or its instances, but it helps implement the real behaviors and isn't very useful outside the class, so I'll namespace it inside it." If the features are useful outside the class, you'd just make it a plain top-level function rather putting it inside the class at all. It is advantageous to use #staticmethod where appropriate; it's a little faster to call than an instance method, so if you don't need the instance, #staticmethod will speed up your code a bit (note: This may not be true in 3.7+, where they added an optimization to avoid the creation of bound methods, which may speed up instance/class methods).
#classmethod basically has two use cases:
(Primary) Defining alternate constructors in a subclass friendly way (the cls it receives is the actual subclass, if applicable, not just the class it was defined in)
(Mostly unnecessary) As an alternative to #staticmethod when the method needs to call other static methods and you'd rather not have to refer to the class by name over and over
Point is, #staticmethod is mostly for when you're opting out of OOP, and #classmethods are for niche use cases; instance methods are just more useful, so they're the default. Beyond that, as a historical note, static and class methods were introduced later, so making them the default would have broken all existing Python code, for no real benefit.
The main reason to use #staticmethod over instance methods with an ignored self (when self isn't needed) is that it will continue to work when called on the class itself, not just on instances of the class; if you tried to call MyClass.notreallystatic(), it would die for lack of a self, while MyClass.actuallystatic() would work.
Using WTForms form definition classes as an example:
class RegistrationForm(Form):
username = StringField('Username', [validators.Length(min=4, max=25)])
email = StringField('Email Address', [validators.Length(min=6, max=35)])
accept_rules = BooleanField('I accept the site rules', [validators.InputRequired()])
and looking at the source of the library it seems WTForms allows a user to define a very simple class of a customised form structure (as above), which in turn then gets used to construct a new field class which is not instantiated when the class is generated.
I've read a number of tutorials about class factories and metaclasses and the general consensus is to avoid metaclasses and use things like class decorators instead. The problem is the tutorials either start importing extra libraries eg: import six, mix explanations of different Python versions together, use overly complex examples or advise not to use metaclasses at all.
Please can somebody provide a very simple explanation (for Python 3) of how to use a simple class definition (like the WTForms example above) along with metaclasses to customise a brand new construction of a class without actually instantiating the class when it's constructed.
Edit: Apologies for finding it difficult to explain what my end goal is but as I have gone through tutorials it has been unclear as to whether class decorators, metaclasses, magic methods (call, new, init) or a combination of such are what I needed to achieve what I visualised, or if what I was visualising was the wrong way of doing things. Unfortunately it seems impossible to judge if my goal was wrong without being able to understand the mechanisms needed to achieve it. I've realised metaclasses are the way to go and just need pointing in the right direction for a very simple metaclass example done the Python 3.x way.
You can create classes dynamically - with no custom metaclasses and no decorators with what looks to the programmer as simple function call.
Just make a call to Python's builtin type with three parameters:
the name of the class, a tuple with its bases, and a mapping object with its namespace (i.e. a dictionary containing the attributes and methods you would ordinarily define on the class body).
def __init__(self):
...
namespace = {
'__init__': init,
'name': 'default name'
}
MyClass = type("MyClass", (object,), namespace)
You loose some features that are only possible due to the compiler doing a couple special things during building functions declared within a class body - mostly the ability to use paramterless super and name mangling of attributes starting with __, but that is it.
That said it should be noted this is not with "no metaclasses". "type" is itself a metaclass - the default Python metaclass for all objects - and is calling a metaclass that create a class. There is no other way to create a class. A "class decorator" is just a method that can makes changes to a class object after it is created.
Any function or method that yields a new, dynamic class, will have inside it to, at some point, call type or other metaclass. In the same mood, a "metaclass" does not create dynamic classes by itself - it needs do be either used in a class body declaration, or called with (at least) the same parameters used for calling type.
As for the recommendations for "class decorators" instead of metaclasses, I am not sure is that true (beyond the fact there is no way a "class decorator" can create classes dynamically by itself): their main drawback is that there is no ordinary way for subclasses of decorated classes to have the parent's class decorators applied to themselves automatically, while metaclasses are inherited.
In Python 3.6 you have the __init_subclass__ protocol which, yes, can avoid a lot of the traditional uses for a metaclass (but still, it won't "create classes dynamically" - calling type does that).
Let's say I define a base class that provides some methods that will likely be overridden. It's not required though, as the base class provides naive default implementations. How can I highlight those methods best?
In C++, I would just use virtual but Python is a dynamic language where methods can always be overridden without marking them. I am rather looking for a hint here. Ideally, this is faster to see than a textual explanation in the docstring and easier to understand to others than a custom decorator.
I once read (I think on a page from Microsoft) that it's a good way to use static classes, when you don't NEED two or more instances of a class.
I'm writing a program in Python. Is it a bad style, if I use #classmethod for every method of a class?
Generally, usage like this is better done by just using functions in a module, without a class at all.
It's terrible style, unless you actually need to access the class.
A static method [...] does not translate to a Python classmethod. Oh sure, it results in more or less the same effect, but the goal of a classmethod is actually to do something that's usually not even possible [...] (like inheriting a non-default constructor). The idiomatic translation of a [...] static method is usually a module-level function, not a classmethod or staticmethod.
source
In my experience creating a class is a very good solution for a number of reasons. One is that you wind up using the class as a 'normal' class (esp. making more than just one instance) more often than you might think. It's also a reasonable style choice to stick with classes for everthing; this can make it easier for others who read/maintain your code, esp if they are very OO - they will be comfortable with classes. As noted in other replies, it's also reasonable to just use 'bare' functions for the implementation. You may wish to start with a class and make it a singleton/Borg pattern (lots of examples if you googlefor these); it gives you the flexibility to (re)use the class to meet other needs. I would recommend against the 'static class' approach as being non-conventional and non-Pythonic, which makes it harder to read and maintain.
There are a few approaches you might take for this. As others have mentioned, you could just use module-level functions. In this case, the module itself is the namespace that holds them together. Another option, which can be useful if you need to keep track of state, is to define a class with normal methods (taking self), and then define a single global instance of it, and copy its instance methods to the module namespace. This is the approach taken by the standard library "random" module -- take a look at lib/python2.5/random.py in your python directory. At the bottom, it has something like this:
# Create one instance, seeded from current time, and export its methods
# as module-level functions. [...]
_inst = Random()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
...
Or you can take the basic approach you described (though I would recommend using #staticmethod rather than #classmethod in most cases).
You might actually want a singleton class rather than a static class:
Making a singleton class in python
How do you decide between using decorators and inheritance when both are possible?
E.g., this problem has two solutions.
I'm particularly interested in Python.
Decorators...:
...should be used if what you are trying to do is "wrapping". Wrapping consists of taking something, modifying (or registering it with something), and/or returning a proxy object that behaves "almost exactly" like the original.
...are okay for applying mixin-like behavior, as long as you aren't creating a large stack of proxy objects.
...have an implied "stack" abstraction:
e.g.
#decoA
#decoB
#decoC
def myFunc(...): ...
...
Is equivalent to:
def myFunc(...): ...
...
myFunc = decoA(decoB(decoC(myFunc))) #note the *ordering*
Multiple inheritance...:
... is best for adding methods to classes; you cannot use it to decorate functions easily. In this context, it can be used to achieve mixin-like behavior if all you need is a set of "duck-typing style" extra methods.
... may be a bit unwieldy if your problem is not a good match for it, with issues with superclass constructors, etc. For example, the subclasses __init__ method will not be called unless it is called explicitly (via the method-resolution-order protocol)!
To sum up, I would use decorators for mixin-like behavior if they didn't return proxy objects. Some examples would include any decorator which returns the original function, slightly modified (or after registering it somewhere or adding it to some collection).
Things you will often find decorators for (like memoization) are also good candidates, but should be used in moderation if they return proxy objects; the order they are applied matter. And too many decorators on top of one another is using them in a way they aren't intended to be used.
I would consider using inheritance if it was a "classic inheritance problem", or if all I needed for the mixin behavior were methods. A classic inheritance problem is one where you can use the child wherever you could use the parent.
In general, I try to write code where it is not necessary to enhance arbitrary things.
The problem you reference is not deciding between decorators and classes. It is using decorators, but you have the option of using either:
a decorator, which returns a class
a decorator, which returns a function
A decorator is just a fancy name for the "wrapper" pattern, i.e. replacing something with something else. The implementation is up to you (class or function).
When deciding between them, it's completely a matter of personal preference. You can do everything you can do in one with the other.
if decorating a function, you may prefer decorators which return proxy functions
if decorating a class, you may prefer decorators which return proxy classes
(Why is it a good idea? There may be assumptions that a decorated function is still a function, and a decorated class is still a class.)
Even better in both cases would be to use a decorator which just returns the original, modified somehow.
edit: After better understanding your question, I have posted another solution at Python functools.wraps equivalent for classes
The other answers are quite great, but I wanted to give a succinct list of pros and cons.
The main advantage of mixins is that the type can be checked at runtime using isinstance and it can be checked with linters like MyPy. Like all inheritance, it should be used when you have an is-a relationship. For example dataclass should probably have been a mixin in order to expose dataclass-specific introspection variables like the list of dataclass fields.
Decorators should be preferred when you don't have an is-a relationship. For example, a decorator that propagates documentation from another class, or registers a class in some collection.
Decoration typically only affects the class it decorates, but not classes that inherit from the base class:
#decorator
class A:
... # Can be affected by the decorator.
class B(A):
... # Not affected by the decorator in most cases.
Now that Python has __init_subclass__, everything that decorators can do can be done with mixins, and they typically do affect child subclasses:
class A(Mixin):
... # Is affected by Mixin.__init_subclass__.
class B(A):
... # Is affected by Mixin.__init_subclass__.
Mixins have another advantage, which is that they can provide empty base class methods. Child classes can override these methods with some "augmenting" behavior, and then call super. The decorator cannot easily provide such base class methods. This is another way in which mixins are more flexible.
In summary, the questions you should ask when deciding between a mixin and decoration are:
Is there an is-a pattern?
Would you ever call isinstance?
Would you use the mixin in a type annotation?
Do you want the behavior to affect child classes?
Do you need augmenting methods?
In general, lean towards inheritance.
If both are equivalent, I would prefer decorators, since you can use the same decorator for many classes, while inheriting apply to only one specific class.
Personally, I would think in terms of code reuse. Decorator is sometimes more flexible than inheritance.
Let's take caching as an example. If you want to add caching facility to two classes in your system: A and B, with inheritance, you'll probably wind up having ACached and BCached. And by overriding some of the methods in these classes, you'll probably duplicate a lot of codes for the same caching logic. But if you use decorator in this case, you only need to define one decorator to decorate both classes.
So, when deciding which one to use, you may first want to check if the extended functionality is only specific to this class or if the same extended functionality can be reused in other parts of your system. If it cannot be reused, then inheritance should probably do the job. Otherwise, you can think about using decorator.