I'm currently coding a C library which provides several modules and
objects.
Let's say that some of these objects are classes called AAA and BBB.
The constructor of AAA needs to get BBB as argument.
So I can run the following code :
from mymodule import AAA
from mymodule import BBB
a = AAA(BBB()))
But, as there is no case where AAA can be used without BBB, I would
like to avoid importing BBB in my Python scripts when I already import
AAA.
For now, I think that reproducing the behavior of the __init__.py file
could be a good way to do this, but how can I code that using only the
C API ?
Are there any other solutions ? Is this kind of importation a good
idea ?
Greetings,
Cyrille Bagard
> Hi everyone,
>
> I'm currently coding a C library which provides several modules and
> objects.
>
> Let's say that some of these objects are classes called AAA and BBB. The
> constructor of AAA needs to get BBB as argument.
>
> So I can run the following code :
>
> from mymodule import AAA
> from mymodule import BBB
>
> a = AAA(BBB()))
>
> But, as there is no case where AAA can be used without BBB, I would like
> to avoid importing BBB in my Python scripts when I already import AAA.
Since AAA must take an argument of BBB, then give it a default:
# in mymodule
def AAA(arg=BBB()):
...
# in another module
from mymodule import AAA
a = AAA()
Or do this:
from mymodule import AAA, BBB
a = AAA(BBB())
> For now, I think that reproducing the behavior of the __init__.py file
> could be a good way to do this, but how can I code that using only the C
> API ?
What is the behaviour of the __init__.py file?
--
Steven
Not yet used, but I read this file is run by Python when a module of a
package is imported.
So you can insert default importations in it.
Then why do you need to explicitely pass BBB() to AAA constructor? You
could leave AAA constructor with no parameters or with a parameter
with a default BBB() value
def AAA(*args, **kwargs):
param = BBB(*args, **kwargs)
# more code
from mymodule import AAA
AAA(1,2,3) # list of parameters you would have used with BBB.
Saying that, is there any strong reason (meaning design issue) why you don't want to import explicitly BBB ?
Because if the reason is 'It takes too much time', then it's a bad reason.
Cheers,
JM
Some more details about what I'm coding and what I need...
The classes AAA and BBB are just given as examples. In fact, BBB's
constructor accepts several parameters, meaning it can be different
for each creation of AAA. So it can't be simply skipped from the AAA's
one, even if there can be a default value.
Making AAA do the call to BBB is a solution, but, in that case, the
end-user loses the reference to the used BBB instance.
Concerning the reason why I wish to avoid importing, once again AAA
and BBB were just examples. I plan to add more classes, so AAA will
also need CCC, DDD, and so on to work.
It takes time to write the relative importations, that's ok, but I
think it could be more pleasant for the end-user to not have to write
a huge list of "from mymodule import xxx" if it is possible to take
advantage of automatic importations.
Cheers,
> It takes time to write the relative importations, that's ok, but I think
> it could be more pleasant for the end-user to not have to write a huge
> list of "from mymodule import xxx" if it is possible to take advantage
> of automatic importations.
You mean by black magic? Something like this?
>>> GGG = "My really important value"
>>> from mymodule import AAA
>>> print AAA()
"something"
>>> print GGG
<class 'mymodule.GGG'>
>>> print "WTF happened to my important value???"
'magic ate it'
As a general rule, Python does not allow magic. One exception is:
from mymodule import *
however once you have been bitten by it, you will soon learn to avoid it
as almost always a bad idea.
--
Steven
import mymodule as m
and then use:
m.AAA
m.BBB
and so on?
It's not much longer and it avoids 'magic'.
In that particular case, replace automatic by implicit, and you got the
reason why it is not a good idea.
Maybe in your case the C habits clashes to the python habits.
Talking about python, if the user needs to know about BBB, then it has
to import it, perdiod. If the user needs to know about many objects,
then it has to import them all, explicitly.
However it looks like all your objects belong to the same module,
quoting MRAB:
"
Couldn't you just have:
import mymodule as m
and then use:
m.AAA
m.BBB
"
You don't like prefixing your object with the namespace they belong to ?
Well, you should :o)
JM
PS : I would'n have renamed the module, but that falls into personal
preferences.
You're right !
As a C developer, I appreciate to only include <string.h> to deal with
strings, without wondering which other header provides size_t
definition.
> Talking about python, if the user needs to know about BBB, then it has
> to import it, perdiod. If the user needs to know about many objects,
> then it has to import them all, explicitly.
Ok. If this is the Python way of coding, that's ok for me. I will stop
now my quest for an automatic import and work like that.
The most interesting solution I have found until now is using
PyImport_AppendInittab() and PyEval_GetGlobals() functions. But this
also brings lots of problems (mainly namespaces and unloading).
Anyway, the time spent to look for a solution was a nice way to learn
Python internals :)
Cheers,
That would frequently give wrong results unless BBB is explicitly
designed to create immutable instances. I strongly suggest doing the
usual mutable dance:
def AAA(arg=None):
if arg is None:
arg = BBB()
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/
"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan