Automatic import ?

C

C. B.

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.

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
 
S

Steven D'Aprano

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?
 
O

Ovidiu Deac

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.

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
 
J

Jean-Michel Pichavant

C. B. said:
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.

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
Make AAA do the call to BBB:

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
 
C

C. B.

At first, thank you all for your answers.

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,
 
S

Steven D'Aprano

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?

'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.
 
M

MRAB

C. B. said:
At first, thank you all for your answers.

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.
Couldn't you just have:

import mymodule as m

and then use:

m.AAA
m.BBB

and so on?

It's not much longer and it avoids 'magic'.
 
J

Jean-Michel Pichavant

C. B. said:
[snip]
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,

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 :eek:)

JM


PS : I would'n have renamed the module, but that falls into personal
preferences.
 
C

C. B.

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.

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,
 
A

Aahz

Since AAA must take an argument of BBB, then give it a default:

# in mymodule
def AAA(arg=BBB()):
...

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()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top