Python Module Initialization - python

Is it bad practice to initialize the objects in the module, in the module code?
in Module.py:
class _Foo(object):
def __init__(self):
self.x = 'Foo'
Foo = _Foo()
Than in user code, you could:
>>> from Module import Foo
>>> print Foo.x
'Foo'
>>>
...without having to initialize the Foo class in the user code. Of course, only useful if you don't need arguments to initialize the object.
Is there a reason not to do this?

Typically, you only want to run the minimum necessary to have your module usable. This will have an overall effect on performance (loading time), and can also make debugging easier.
Also, usually more than one instance will be created from any given class.
Having said that, if you have good reasons (such as only wanting one instance of a class), then certainly initialize it at load time.

I do this sometimes, when it's really convenient, but I tend to do foo = Foo(). I really dislike the idea of making the class appear private, and making the instance available as Foo. As a developer using your code I'd find that pretty disconcerting.

Related

How can I use super() in both elegant and safe (regarding Python module reloading) way?

I discovered an annoying behaviour of reload() (both Python 2 builtin and from importlib) that I am trying to walkarround.
I am analysing data in interactive Python interpreter. My code is organised in modules (both Python 2 and 3 compatible) which I often change.
Restarting the interpreter is not feasible due to long time of loading data, so I prefer to recursively reload modules instead.
The problem is that reload() updates the code but preserves the module global scope (it applies to Python 3 importlib.reload() as well). It seems to be harmful for methods using super() (it took me a while to realise what is going on).
The minimal failing example for a module bar.py:
class Bar(object):
def __init__(self):
super(Bar, self).__init__()
is:
>>> import bar
>>> class Foo(bar.Bar):
... pass
...
>>> reload(bar)
<module 'bar' from '[censored]/bar.py'>
>>> Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[censored]/bar.py", line 3, in __init__
super(Bar, self).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of type
I may:
use super() without arguments in Python 3 manner (which is not
compatible with Python 2),
abandon it and call Bar.__init__(self) instead (which is harder to
maintain and discouraged),
monkey-patch the class adding a class attribute containing a circular
reference to the class itself.
None of the ideas I like. Is there any other way of dealing with the issue?
You can't, because it's basically impossible to do anything elegantly and safely where module reloading is concerned. That kind of thing is super tricky to get right.
The specific way that problem is manifesting here is that Foo's superclass is still the old Bar, but the old Bar refers to itself by name, and the Bar name now refers to the new Bar in the namespace where it's looking. The old Bar is trying to pass the new Bar to super.
I can give you some options. All of them are inelegant and unsafe and probably going to give you weird surprises eventually, but all that is also true about module reloading.
Probably the most easily-understood option is to rerun the Foo class definition to get a new Foo class descending from the new Bar:
reload(bar)
class Foo(bar.Bar):
pass
New instances of Foo will then use the new Bar, and will not experience problems with super. Old instances will use the old Foo and the old Bar. They're not going to have problems with __init__, because that already ran, but they're likely to have other problems.
Another option you can take is to update Foo's superclass so Foo now descends from the new Bar:
reload(bar)
Foo.__bases__ = (bar.Bar,)
New and old instances of Foo will then use the new Bar. Depending on what you changed in Bar, the new class may not be compatible with the old instances, especially if you changed what data Bar keeps on its instances or how Bar.__init__ performs initialization.
Sound like what you really want it to do re-import the module. The following allow that (in both Python 2 and 3).
import bar
import sys
class Foo(bar.Bar):
pass
# Manually reload module.
_saved_reference = sys.modules['bar'] # Needed for Python 2.
del sys.modules['bar']
import bar # Re-import instead of reload().
Foo() # No error.

Use module as class instance in Python

TL; DR
Basically the question is about hiding from the user the fact that my modules have class implementations so that the user can use the module as if it has direct function definitions like my_module.func()
Details
Suppose I have a module my_module and a class MyThing that lives in it. For example:
# my_module.py
class MyThing(object):
def say():
print("Hello!")
In another module, I might do something like this:
# another_module.py
from my_module import MyThing
thing = MyThing()
thing.say()
But suppose that I don't want to do all that. What I really want is for my_module to create an instance of MyThing automatically on import such that I can just do something like the following:
# yet_another_module.py
import my_module
my_module.say()
In other words, whatever method I call on the module, I want it to be forwarded directly to a default instance of the class contained in it. So, to the user of the module, it might seem that there is no class in it, just direct function definitions in the module itself (where the functions are actually methods of a class contained therein). Does that make sense? Is there a short way of doing this?
I know I could do the following in my_module:
class MyThing(object):
def say():
print("Hello!")
default_thing = MyThing()
def say():
default_thing.say()
But then suppose MyThing has many "public" methods that I want to use, then I'd have to explicitly define a "forwarding" function for every method, which I don't want to do.
As an extension to my question above, is there a way to achieve what I want above, but also be able to use code like from my_module import * and be able to use methods of MyThing directly in another module, like say()?
In module my_module do the following:
class MyThing(object):
...
_inst = MyThing()
say = _inst.say
move = _inst.move
This is exactly the pattern used by the random module.
Doing this automatically is somewhat contrived. First, one needs to find out which of the instance/class attributes are the methods to export... perhaps export only names which do not start with _, something like
import inspect
for name, member in inspect.getmembers(Foo(), inspect.ismethod):
if not name.startswith('_'):
globals()[name] = member
However in this case I'd say that explicit is better than implicit.
You could just replace:
def say():
return default_thing.say()
with:
say = default_thing.say
You still have to list everything that's forwarded, but the boilerplate is fairly concise.
If you want to replace that boilerplate with something more automatic, note that (details depending on Python version), MyThing.__dict__.keys() is something along the lines of ['__dict__', '__weakref__', '__module__', 'say', '__doc__']. So in principle you could iterate over that, skip the __ Python internals, and call setattr on the current module (which is available as sys.modules[__name__]). You might later regret not listing this stuff explicitly in the code, but you could certainly do it.
Alternatively you could get rid of the class entirely as use the module as the unit of encapsulation. Wherever there is data on the object, replace it with global variables. "But", you might say, "I've been warned against using global variables because supposedly they cause problems". The bad news is that you've already created a global variable, default_thing, so the ship has sailed on that one. The even worse news is that if there is any data on the object, then the whole concept of what you want to do: module-level functions that mutate a shared global state, carries with it most of the problems of globals.
Not Sure why this wouldn't work.
say = MyClass().say()
from my_module import *
say
>>Hello!

Where is the best place to put support functions in a class?

In Python, I have a class that I've built.
However, there is one method where I apply a rather specific type of substring-search procedure. This procedure could be a standalone function by itself (it just requires a needle a haystack string), but it feels odd to have the function outside the class, because my class depends on it.
What is the typical design paradigm for this? Is it typical to just have myClassName.py with the main class, as well as all the support functions outside the class itself, in the same file? Or is it better to have the support function embedded within the class at the expense of modularity?
You can create a staticmethod, like so:
class yo:
#staticmethod
def say_hi():
print "Hi there!"
Then, you can do this:
>>> yo.say_hi()
Hi there!
>>> a = yo()
>>> a.say_hi()
Hi there!
They can be used non-statically, and statically (if that makes sense).
About where to put your functions...
If a method is required by a class, and it is appropriate for the method to perform data that is specific to the class, then make it a method. This is what you would want:
class yo:
self.message = "Hello there!"
def say_message(self):
print self.message
My say_message relies on the data that is particular to the instance of a class.
If you feel the need to have a function, in addition to the class method, by all means go ahead. Use whichever one is more appropriate in your script. There are many examples of this, including in the python built-ins. Take generator objects for example:
a = my_new_generator()
a.next()
Can also be done as:
a = my_new_generator()
next(a)
Use whichever is more appropriate, and obviously whichever one is more readable. :)
If you can think or any reason to override this function one day, make it a staticmethod, else a plain function is just ok - FWIW, your class probably depends on much more than this simple function. And if you cannot think of any reason for anyone else to ever use this function, keep it in the same module as your class.
As a side note: "myClassName.py" is definitly unpythonic. First because module names should be all_lower, then because the one-module-per-class stuff is a nonsense in Python - we group related classes and functions (and exceptions and whatnots) together.
If the search method you are talking about is really so specific and you will never need to reuse it somewhere else, I do not see any reason to make it static. The fact that it doesn't require access to instance variables doesn't make it static by definition.
If there is a possibility, that this method is going to be reused, refactor it into a helper/utility class (no static again).
ADDED:
Just wanted to add, that when you consider something being static or not, think about how method name relates to the class name. Does this method name makes more sense when used in class context or object context?

Can Python do DI seamlessly without relying on a service locator?

I'm coming from the C# world, so my views may be a little skewed. I'm looking to do DI in Python, however I'm noticing a trend with libraries where they all appear to rely on a service locator. That is, you must tie your object creation to the framework, such as injectlib.build(MyClass) in order to get an instance of MyClass.
Here is an example of what I mean -
from injector import Injector, inject
class Inner(object):
def __init__(self):
self.foo = 'foo'
class Outer(object):
#inject(inner=Inner)
def __init__(self, inner=None):
if inner is None:
print('inner not provided')
self.inner = Inner()
else:
print('inner provided')
self.inner = inner
injector = Injector()
outer = Outer()
print(outer.inner.foo)
outer = injector.get(Outer)
print(outer.inner.foo)
Is there a way in Python to create a class while automatically inferring dependency types based on parameter names? So if I have a constructor parameter called my_class, then an instance of MyClass will be injected. Reason I ask is that I don't see how I could inject a dependency into a class that gets created automatically via a third party library.
To answer the question you explicitly asked: no, there's no built-in way in Python to automatically get a MyClass object from a parameter named my_class.
That said, neither "tying your object creation to the framework" nor the example code you gave seem terribly Pythonic, and this question in general is kind of confusing because DI in dynamic languages isn't really a big deal.
For general thoughts about DI in Python I'd say this presentation gives a pretty good overview of different approaches. For your specific question, I'll give two options based on what you might be trying to do.
If you're trying to add DI to your own classes, I would use paramaters with default values in the constructor, as that presentation shows. E.g:
import time
class Example(object):
def __init__(self, sleep_func=time.sleep):
self.sleep_func = sleep_func
def foo(self):
self.sleep_func(10)
print('Done!')
And then you could just pass in a dummy sleep function for testing or whatever.
If you're trying to manipulate a library's classes through DI, (not something I can really imagine a use case for, but seems like what you're asking) then I would probably just monkey patch those classes to change whatever needed changing. E.g:
import test_module
def dummy_sleep(*args, **kwargs):
pass
test_module.time.sleep = dummy_sleep
e = test_module.Example()
e.foo()

Python: How should I make instance variables available?

Suppose I have:
class myclass:
def __init__(self):
self.foo = "bar"
where the value of foo needs to be available to users of myclass. Is it OK to just read the value of foo directly from an instance of myclass? Should I add a get_foo method to myclass or perhaps add a foo property? What's the best practice here?
The applicable Python maxim would be "we're all adults here" - if users need direct access to the value of foo, let them access it directly. A getter or property would make sense if you need to run some code when it's accessed, otherwise the direct way is best.
Also, you can always transparently turn it into a property later if you need to.
I think it should be alright to expose "foo" as it is. Even if you hide it behind a "getter", an insistent user will still be able to access it. As tzaman mentioned "we're all adults here".
If you wish to restrict the usage a bit (ie. make it harder to set), you might consider exposing it using a property. Properties are particularly handy if you need to expose an attribute that has been derived based on others.
Python tutorial has a very nice and concise discussion about this, so check it out. As there is no access control in Python, and recomendation is: if there is something you would make private in C++, start the name with an _ in Python and "play nice". Otherwise just access it directly.
My suggestion, go for the easiest! Directly access the instance variables.
You can argue that if you change the inner representation of your data, you would like to access the data the same way without caring about the inner representation. But hey ! if you have get_foo and set_foo, semanticaly, it means you're changing a variable. So just do so :)
PS: I love the ruby approach there :)
Depends on what you mean by "available to users of myclass". I think that you are talking about a class attribute, like this:
>>> class Myclass(object):
... foo = "bar"
...
>>> a = Myclass()
>>> a.foo
'bar'
>>> b = Myclass()
>>> b.foo
'bar'
>>> Myclass.foo = "zot"
>>> a.foo
'zot'
>>> b.foo
'zot'
>>>

Categories

Resources