In my application I have to maintain some global application state and global application wide methods like currently connected users, total number of answers, create an application config file etc. There are two options:
Make a separate appstate.py file with global variables with functions over them. It looks fine initially but it seems that I am missing something in clarity of my code.
Create a class AppState with class functions in a appstate.py file, all other modules have been defined by their specific jobs. This looks fine. But now I have to write longer line like appstate.AppState.get_user_list(). Moreover, the methods are not so much related to each other. I can create separate classes but that would be too many classes.
EDIT: If I use classes I will be using classmethods. I don't think there is a need to instantiate the class to an object.
Sounds like the classic conundrum :-).
In Python, there's nothing dirty or shameful about choosing to use a module if that's the best approach. After all, modules, functions, and the like are, in fact, first-class citizens in the language, and offer introspection and properties that many other programming languages offer only by the use of objects.
The way you've described your options, it kinda sounds like you're not too crazy about a class-based approach in this case.
I don't know if you've used the Django framework, but if not, have a look at the documentation on how it handle settings. These are app-wide, they are defined in a module, and they are available globally. The way it parses the options and expose them globally is quite elegant, and you may find such an approach inspiring for your needs.
The second approach is only significantly different from the first approach if you have application state stored in an instance of AppState, in which case your complaint doesn't apply. If you're just storing stuff in a class and using static/class methods, your class is no different than a module, and it would be pythonic to instead actually have it as a module.
The second approach seems better. I'd use the first one only for configuration files or something.
Anyway, to avoid the problem you could always:
from myapp.appstate import AppState
That way you don't have to write the long line anymore.
Why not go with an instance of that class? That way you might even be able later on to have 2 different "sessions" running, depending on what instance you use. It might make it more flexible. Maybe add some method get_appstate() to the module so it instanciates the class once. Later on if you might want several instances you can change this method to eventually take a parameter and use some dictionary etc. to store those instances.
You could also use property decorators btw to make things more readable and have the flexibility of storing it how and where you want it stores.
I agree that it would be more pythonic to use the module approach instead of classmethods.
BTW, I am not such a big fan of having things available globally by some "magic". I'd rather use some explicit call to obtain that information. Then I know where things come from and how to debug it when things fail.
Consider this example:
configuration
|
+-> graphics
| |
| +-> 3D
| |
| +-> 2D
|
+-> sound
The real question is: What is the difference between classes and modules in this hierarchy, as it could be represented by both means?
Classes represent types. If you implement your solution with classes instead of modules, you are able to check a graphics object for it's proper type, but write generic graphics functions.
With classes you can generate parametrized values. This means it is possible to initialize differently the sounds class with a constructor, but it is hard to initialize a module with different parameters.
The point is, that you really something different from the modeling standpoint.
I would go with the classes route as it will better organize your code. Remember that for readability you can do this:
from appstate import AppSate
I'd definitely go for the second option : having already used the first one, I'm now forced to refactor, as my application evolved and have to support more modular constructs, so I now need to handle multiple simulataneous 'configurations'.
The second approach is, IMO, more flexible and future proof. To avoid the longer lines of code, you could use from appstate import AppState instead of just import appstate.
Related
So, I have two scripts temperature.py and rain.py. These two scripts do the same thing: open a file, update it and then save it. The purpose of the functions is the same but the functions do it differently for each script.
My question is should I give the same name, ex. update(), to both scripts, all it should be different ?
I am going to import them like below:
import temperature
import rain
I would propose to use the same names, especially if you are not up to from temperature import * or similar nastinesses. The way you write you want to do it, there is no problem by calling rain.update() and temperature.update().
But maybe you should reconsider if your two "modules" shouldn't be better two classes which inherit from each other or at least from a common base class. If you want two things to "do the same, but differently", then overriding an inherited behaviour is the object-oriented way to do it. Maybe the two update()s even have something in common which both need to do (which is a very typical case); that could then be done in a base class then.
And even if you now would answer "no, they have nothing in common", I think I feel the idea of them having something in common on a more theoretical level. In that case, maybe later versions of your software would benefit from the different architecture I propose.
What about making the function specific and descriptive to the context?
from temperature import update_temperature
from rain import update_rain
Naming like this provides a lesser chance of naming conflicts (like both files having an update(), or even a third-party package having it's own update()).
It provides a clear understanding of what exactly your code is doing; updating the temperature (not the units temperature.update_units, or the location temperature.update_location) and states it.
When is a class more useful to use than a function? Is there any hard or fast rule that I should know about? Is it language dependent? I'm intending on writing a script for Python which will parse different types of json data, and my gut feeling is that I should use a class to do this, versus a function.
You should use a class when your routine needs to save state. Otherwise a function will suffice.
First of all, I think that isn't language-dependent (if the language permit you to define classes and function as well).
As a general rule I can tell you that a Class wrap into itself a behaviour. So, if you have a certain type of service that you have to implement (with, i.e. different functions) a class is what you're lookin' for.
Moreover classes (say object that is more correct) has state and you can instantiate more occurrences of a class (so different objects with different states).
Not less important, a class can be inearthed: so you can overwrite a specific behaviour of your function only with small changes.
the class when you have the state - something that should be persistent across the calls
the function in other cases
exception: if your class is only storing couple of values and has a single method besides __init__, you should better use the function
For anything non-trivial, you should probably be using a class. I tend to limit all of my "free-floating" functions to a utils.py file.
This is language-dependent.
Some languages, like Java, insist that you use a class for everything. There's simply no concept of a standalone function.
Python isn't like that. It's perfectly OK - in fact recommended - to define functions standalone, and related functions can be grouped together in modules. As others have stated, the only time you really want a class in Python is when you have state that you need to keep - ie, encapsulating the data within the object.
My first "serious" language was Java, so I have comprehended object-oriented programming in sense that elemental brick of program is a class.
Now I write on VBA and Python. There are module languages and I am feeling persistent discomfort: I don't know how should I decompose program in a modules/classes.
I understand that one module corresponds to one knowledge domain, one module should ba able to test separately...
Should I apprehend module as namespace(c++) only?
I don't do VBA but in python, modules are fundamental. As you say, the can be viewed as namespaces but they are also objects in their own right. They are not classes however, so you cannot inherit from them (at least not directly).
I find that it's a good rule to keep a module concerned with one domain area. The rule that I use for deciding if something is a module level function or a class method is to ask myself if it could meaningfully be used on any objects that satisfy the 'interface' that it's arguments take. If so, then I free it from a class hierarchy and make it a module level function. If its usefulness truly is restricted to a particular class hierarchy, then I make it a method.
If you need it work on all instances of a class hierarchy and you make it a module level function, just remember that all the the subclasses still need to implement the given interface with the given semantics. This is one of the tradeoffs of stepping away from methods: you can no longer make a slight modification and call super. On the other hand, if subclasses are likely to redefine the interface and its semantics, then maybe that particular class hierarchy isn't a very good abstraction and should be rethought.
It is matter of taste. If you use modules your 'program' will be more procedural oriented. If you choose classes it will be more or less object oriented. I'm working with Excel for couple of months and personally I choose classes whenever I can because it is more comfortable to me. If you stop thinking about objects and think of them as Components you can use them with elegance. The main reason why I prefer classes is that you can have it more that one. You can't have two instances of module. It allows me use encapsulation and better code reuse.
For example let's assume that you like to have some kind of logger, to log actions that were done by your program during execution. You can write a module for that. It can have for example a global variable indicating on which particular sheet logging will be done. But consider the following hypothetical situation: your client wants you to include some fancy report generation functionality in your program. You are smart so you figure out that you can use your logging code to prepare them. But you can't do log and report simultaneously by one module. And you can with two instances of logging Component without any changes in their code.
Idioms of languages are different and thats the reason a problem solved in different languages take different approaches.
"C" is all about procedural decomposition.
Main idiom in Java is about "class or Object" decomposition. Functions are not absent, but they become a part of exhibited behavior of these classes.
"Python" provides support for both Class based problem decomposition as well as procedural based.
All of these uses files, packages or modules as concept for organizing large code pieces together. There is nothing that restricts you to have one module for one knowledge domain.
These are decomposition and organizing techniques and can be applied based on the problem at hand.
If you are comfortable with OO, you should be able to use it very well in Python.
VBA also allows the use of classes. Unfortunately, those classes don't support all the features of a full-fleged object oriented language. Especially inheritance is not supported.
But you can work with interfaces, at least up to a certain degree.
I only used modules like "one module = one singleton". My modules contain "static" or even stateless methods. So in my opinion a VBa module is not namespace. More often a bunch of classes and modules would form a "namespace". I often create a new project (DLL, DVB or something similar) for such a "namespace".
OK I've got 2 really big classes > 1k lines each that I currently have split up into multiple ones. They then get recombined using multiple inheritance. Now I'm wondering, if there is any cleaner/better more pythonic way of doing this. Completely factoring them out would result in endless amounts of self.otherself.do_something calls, which I don't think is the way it should be done.
To make things clear here's what it currently looks like:
from gui_events import GUIEvents # event handlers
from gui_helpers import GUIHelpers # helper methods that don't directly modify the GUI
# GUI.py
class GUI(gtk.Window, GUIEvents, GUIHelpers):
# general stuff here stuff here
One problem that is result of this is Pylint complaining giving me trillions of "init not called" / "undefined attribute" / "attribute accessed before definition" warnings.
EDIT:
You may want to take a look at the code, to make yourself a picture about what the whole thing actually is.
http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/
Please note, I'm really trying anything to keep this thing as DRY as possible, I'm using pylint to detect code duplication, the only thing it complains about are the imports.
If you want to use multiple inheritance to combine everything into one big class (it might make sense to do this), then you can refactor each of the parent classes so that every method and property is either private (starts with '__') or has a short 2-3 character prefix unique to that class. For example, all the methods and properties in your GUIEvents class could start with ge_, everything in GUIHelpers could start with gh_. By doing this, you'll get achieve some of the clarity of using separate sub-class instances (self.ge.doSomething() vs self.ge_doSomething()) and you'll avoid conflicting member names, which is the main risk when combining such large classes into one.
Start by finding classes that model real world concepts that your application needs to work with. Those are natural candidates for classes.
Try to avoid multiple inheritance as much as possible; it's rarely useful and always somewhat confusing. Instead, look to use functional composition ("HAS-A" relationships) to give rich attributes to your objects made of other objects.
Remember to make each method do one small, specific thing; this necessarily entails breaking up methods that do too many things into smaller pieces.
Refactor cases where you find many such methods are duplicating each other's functionality; this is another way to find natural collections of functionality that deserve to be in a distinct class.
I think this is more of a general OO-design problem than Python problem. Python pretty much gives you all the classic OOP tools, conveniently packaged. You'd have to describe the problem in more detail (e.g. what do the GUIEvents and GUIHelpers classes contain?)
One Python-specific aspect to consider is the following: Python supports multiple programming paradigms, and often the best solution is not OOP. This may be the case here. But again, you'll have to throw in more details to get a meaningful answer.
Your code may be substantially improved by implementing a Model-View-Controller design. Depending on how your GUI and tool are setup, you may also benefit from "widgetizing" portions of your GUI, so that rather than having one giant Model-View-Controller, you have a main Model-View-Controller that manages a bunch of smaller Model-View-Controllers, each for distinct portions of your GUI. This would allow you to break up your tool and GUI into many classes, and you may be able to reuse portions of it, reducing the total amount of code you need to maintain.
While python does support multiple programming paradigms, for GUI tools, the best solution will nearly always be an Object-Oriented design.
One possibility is to assign imported functions to class attributes:
In file a_part_1.py:
def add(self, n):
self.n += n
def __init__(self, n):
self.n = n
And in main class file:
import a_part_1
class A:
__init__ = a_part_1.__init__
add = a_part_1.add
Or if you don't want to update main file when new methods are added:
class A: pass
import a_part_1
for k, v in a_part_1.__dict__.items():
if callable(v):
setattr(A,k,v)
I have a class called Path for which there are defined about 10 methods, in a dedicated module Path.py. Recently I had a need to write 5 more methods for Path, however these new methods are quite obscure and technical and 90% of the time they are irrelevant.
Where would be a good place to put them so their context is clear? Of course I can just put them with the class definition, but I don't like that because I like to keep the important things separate from the obscure things.
Currently I have these methods as functions that are defined in a separate module, just to keep things separate, but it would be better to have them as bound methods. (Currently they take the Path instance as an explicit parameter.)
Does anyone have a suggestion?
If the method is relevant to the Path - no matter how obscure - I think it should reside within the class itself.
If you have multiple places where you have path-related functionality, it leads to problems. For example, if you want to check if some functionality already exists, how will a new programmer know to check the other, less obvious places?
I think a good practice might be to order functions by importance. As you may have heard, some suggest putting public members of classes first, and private/protected ones after. You could consider putting the common methods in your class higher than the obscure ones.
If you're keen to put those methods in a different source file at any cost, AND keen to have them at methods at any cost, you can achieve both goals by using the different source file to define a mixin class and having your Path class import that method and multiply-inherit from that mixin. So, technically, it's quite feasible.
However, I would not recommend this course of action: it's worth using "the big guns" (such as multiple inheritance) only to serve important goals (such as reuse and removing repetition), and separating methods out in this way is not really a particularly crucial goal.
If those "obscure methods" played no role you would not be implementing them, so they must have SOME importance, after all; so I'd just clarify in docstrings and comments what they're for, maybe explicitly mention that they're rarely needed, and leave it at that.
I would just prepend the names with an underscore _, to show that the reader shouldn't bother about them.
It's conventionally the same thing as private members in other languages.
Put them in the Path class, and document that they are "obscure" either with comments or docstrings. Separate them at the end if you like.
Oh wait, I thought of something -- I can just define them in the Path.py module, where every obscure method will be a one-liner that will call the function from the separate module that currently exists. With this compromise, the obscure methods will comprise of maybe 10 lines in the end of the file instead of 50% of its bulk.
I suggest making them accessible from a property of the Path class called something like "Utilties". For example: Path.Utilities.RazzleDazzle. This will help with auto-completion tools and general maintenance.