Automatically exporting all functions (vs manually specifying __all__) - python

I have a helpers.py file which defines about 30 helper functions to be exported as follows:
from helpers import *
To be able to do this, I have added all 30 functions to the __all__ variable. Can I automatically have all functions exported, rather than having to specify each one?

Yes, by simply not specifying __all__.

Actually I think Gandaro is right, you don't have to specify __all__, but if, for some unknown reason, you would have to do it then, you can filter keywords from dir():
__all__ = [ helper for helper in dir() if helper == MY_CONDITION ]

If you don't define __all__ then all of the functions in your module will be imported by calling from helpers import *
If you've got some functions that you'd like to keep private, then you could prefix their names with an underscore. From my testing, this stops the functions from being imported by import *
For example, in helper.py:
def _HiddenFunc():
return "Something"
def AnActualFunc():
return "Hello"
Then:
>>> from helper import *
>>> AnActualFunc()
'Hello'
>>> _HiddenFunc()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_HiddenFunc' is not defined

Related

How does one make shortcuts for long package names in an concise import statement?

Why can't I make a short cut name for a module and use that module to import things?
For example:
import utils.utils as utils
print(utils)
print(utils.make_and_check_dir)
From the print statement we can see that the utils package does indeed have my function but then the following import fails (confusingly to me):
from utils import make_and_check_dir
Why? Is there no way to make a short hand for:
pkg.module
?
Error msg:
<module 'utils.utils' from '/Users/pinocchio/git_project/project/utils/utils.py'>
<function make_and_check_dir at 0x11a428ea0>
Traceback (most recent call last):
File "code.py", line 10, in <module>
from utils import make_and_check_dir
ImportError: cannot import name 'make_and_check_dir' from 'utils' (/Users/pinocchio/git_project/project/utils/__init__.py)
My guess as to why would be that it is a namespace issue. If the capability you described were allowed maybe there could be some issue with calling "utils.make_and_check_dir" and "make_and_check_dir" on its own; maybe there would be some mapping issue, but I'm not sure.
Making a shorthand is pretty simple:
shorthand = utils.make_and_check_dir
So now you can call shorthand in place of utils.make_and_check_dir, passing the same arguments you would to the original function.
Actually what you are doing is right, "alias" using "as". So I think error should be from your modules, like utils could be a function or class rather than being a module. Maybe, try changing names (it avoids confusion and you can figure out the error) of utils and its child utils.
Try reading -
1. http://docs.python.org/reference/simple_stmts.html#import
2. Can you define aliases for imported modules in Python?
This could help you find out any silly mistake, if you had done... :)
Ok I got it I think.
First case :
>>> import X.Y as Z
>>> Z.F1
#No Error
>>> from Z import F1
#ModuleNotFoundError
Second case :
>>> import X.Y as X
>>> from X import F1
#Import Error
So actually, what happens is a namespace collision. When you set an alias like that in 1, Python searches for a module named Z instead of looking at its already declared alias Z.
In case 2, the name X clashes with your package X and Python is confused if that "X" is your package or declared variable...
so the bitter moral is, don't use such clashing names. And its better to declare full alias like "import X.Y.Z as myshortZ".

The behavior of variable and function with leading underscore in a class in Python

When we use from <module/package> import *, none of the names that start with a _ will be imported unless the module’s/package’s __all__ list explicitly contains them.
Is this not applicable to variables and functions of a class?
From the below programs, it seems it's not applicable to variables and function inside a class.
_bar and _check_func both are executed in test_import.py. However, _test_func() throws an error for having leading underscore. Am I missing anything here?
test_var.py
class test:
def __init__(self):
self._bar=15
def test_mod(self):
print("this is test mod function")
def _check_func(self):
print("this is _check_func function")
def _test_func():
print("this is test function var 2")
test_import.py
from test_var import *
p1=test()
print(p1._bar)
p1.test_mod()
p1._check_func()
_test_func()
Output:
15
this is test mod function
this is _check_func function
Traceback (most recent call last):
File "test_import.py", line 8, in <module>
_test_func()
NameError: name '_test_func' is not defined
The underscore rule is imposed by the importer when it sees from test_var import *. In fact, the functions are still in the module namespace and you can still use them:
import test_var
test_var._test_func()
You don't import class methods, just classes so the underscore rule isn't applied. p1._check_func() works for the same reason that test_var._test_func() works: You addressed the variable in its namespace.
You imported test and are accessing its members (with or without underscores) through that namespace (in your example, through the instantiated object p1). test is what you import, test._bar is only accessible through test and is not among the imported symbols.

Bug in Python's documentation?

I am reading http://docs.python.org/2/tutorial/modules.html#more-on-modules and wonder if the following is correct:
Modules can import other modules. It is customary but not required to
place all import statements at the beginning of a module (or script,
for that matter). The imported module names are placed in the
importing module’s global symbol table.
Apparently not:
>>> def foo(): import sys
...
>>> foo()
>>> sys.path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
See http://ideone.com/cLK09v for an online demo.
So, is it a bug in the Python's documentation or I don't understand something?
Yes, this is a documentation error. The import statement imports the names to the current namespace. Usually import is used outside of functions and classes, but as you've discovered, it does work within them. In your example function, the module is imported into the function's local namespace when the function is called. (Which you didn't do, but that wouldn't make it available outside the function anyway.)
The global keyword does work here, however:
def foo():
global sys
import sys
foo()
sys.path
I don't think this is actually an error in the documentation, but more of a mis-interpretation. You simply have a scope issue. You are importing it in the scope of the function foo(). You could certainly do as the documentation suggests and put the import at the bottom of the file or somewhere else in the file that would still have the same global scope as your module. The problem is "The imported module names are placed in the importing module’s global symbol table", where the scope of the module you are importing into is contained in the function foo(), not at the module's global level.

Why __import__() is returning the package instead of the module?

I have this file structure (where the dot is my working directory):
.
+-- testpack
+-- __init__.py
+-- testmod.py
If I load the testmod module with the import statement, I can call a function that is declared within:
>>> import testpack.testmod
>>> testpack.testmod.testfun()
hello
but if I try to do the same using the __import__() function, it doesn't work:
>>> __import__("testpack.testmod").testfun()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
__import__("testpack.testmod").testfun()
AttributeError: 'module' object has no attribute 'testfun'
indeed, it returns the package testpack instead of the module testmod:
>>> __import__("testpack.testmod").testmod.testfun()
hello
How come?
This behaviour is given in the docs:
When the name variable is of the form package.module, normally, the
top-level package (the name up till the first dot) is returned, not
the module named by name. However, when a non-empty fromlist argument
is given, the module named by name is returned.
...
The statement import spam.ham results in this call:
spam = __import__('spam.ham', globals(), locals(), [], -1)
Note how __import__() returns the toplevel module here because this is
the object that is bound to a name by the import statement.
Also note the warning at the top:
This is an advanced function that is not needed in everyday Python
programming, unlike importlib.import_module().
And then later:
If you simply want to import a module (potentially within a package)
by name, use importlib.import_module().
So the solution here is to use importlib.import_module().
It's worth noting that the double underscores either side of a name in Python imply that the object at hand isn't meant to be used directly most of the time. Just as you should generally use len(x) over x.__len__() or vars(x)/dir(x) over x.__dict__. Unless you know why you need to use it, it's generally a sign something is wrong.

Inexplicable NameError with command-line Python

I am working my way through the excellent 'Python The Hard Way' and copied the following code into a file called mystuff.py:
class MyStuff(object):
def __init__(self):
self.tangerine = "And now a thousand years between"
def apple(self):
print "I AM CLASSY APPLES!"
In terminal:
import mystuff
thing = MyStuff()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'MyStuff' is not defined
This has been happening repeatedly with other simple classes today. Can someone tell me what I am doing wrong?
You probably want thing = mystuff.MyStuff() (assuming mystuff is the name of the file where the class MyStuff resides).
The issue here is with how python handles namespaces. You bring something into the current namespace by importing it, but there's a lot of flexibility in how you merge the namespaces from one file into another. For example,
import mystuff
brings everything from the mystuff (module/file level) namespace into your current namespace, but to access it, you need mystuff.function_or_class_or_data. If you don't want to type mystuff all the time, you can change the name you use to reference it in the current module (file):
import mystuff as ms
now, you can acess MyStuff by:
thing = ms.MyStuff()
And (almost) finally, there's the from mystuff import MyStuff. In this form, you bring MyStuff directly into your namespace, but nothing else from mystuff comes into your namespace.
Last, (and this one isn't recommended) from mystuff import *. This works the same as the previous one, but it also grabs everything else in the mystuff file and imports that too.
You are importing the module in to your local namespace, but not the class. If you want to use the class with your current import, you need:
thing = mystuff.MyStuff()
If you want to use the declaration you have, you need:
from mystuff import MyStuff
Ok,I guess u got what u need.But here is what's going on with it
import mystuff
#with this type of import all the names in the `mystuff` module's namespace are not copied into current modules namespace.
So you need to use mystuff.MyStuff()
use from mystuff import * to copy names in the mystuff module's namespace to current module's namespace.Now you can directly use thing=MyStuff()

Categories

Resources