import file (NOT: import file as f) - python

So I have added my scripts path to systaphs and now when I want to use my defs or classes I do:
import myFile as f
print f.FILE.NAME
But this is making my code sometimes look more confusing and I want to get rid of the "f". I made the class FILE to use it like enum in C++, to be usefull and easy to read. How can I import myFile to use my defs of classes like:
import myFile
print FILE.NAME
# Error: NameError: file <maya console> line 3: name 'FILE' is not defined #

You can bind to names from a module in your import:
from myFile import FILE
Importing adds one or more names to your namespace. Using import <module> binds the module name, and using as you get to pick your own name for the module.
Using from <module> import <object> you get to bind any of the module attributes to a name (by default the name of the <object> attribute); you can still use as to pick a different name.
Only the names you import are available. When you use just import myFile, only myFile is set, not any of the attributes on myFile.

I have just tested for you buddy.Here are the two files in the same directory:
File 1#: main.py
def hey():
print 'Hey'
File 2#: main2.py
import main
main.hey()
#or
from main import hey
hey()
C:\Users\Baby>python main2.py
output : Hey
I think it will work for you.

Related

Python: Importing a class from a file only given the class name and a path

I am trying to make a system to load drivers from a given path in a json file.
How can I do this?
I have tried:
import sys
import importlib
import json
jsonfile = open("test.json")
json_contents = json.load(jsonfile)
sys.path.append(json_contents["Path to drivers"])
Driver_Module = importlib.import_module(json_contents["Class File Name"])
print(sys.modules)
from Driver_Module import DriverModuleClass
But I get the error that no module named 'Driver_Module' exists. The problem is that the name of the "Class File Name" is imported in the print as whatever that is.
Without the "From" I get "No Module Named DriverModuleClass" even though that is the name of the class inside the module which is added to the sys.modules already.

Creating Python submodule

I want to create a tool called unifile for saving and opening files
like this unifile.open.yaml("file.yaml").
This is my structure:
unifile
|
├-open
| └--__init__.py
|
└-save
└--__init__.py
Code that call my module:
import unifile
a = unifile.open.yaml("file.yaml")
open/init.py
import yaml
class open():
def yml(self, file_path):
try:
with open(file_path, "r", encoding="utf-8") as yaml_conf:
yaml_file = yaml.safe_load(yaml_conf)
return yaml_file
except OSError:
print("Can't load yaml")
1 error if I import unifile always say:
module unifile has no atribute open
2 error in __init__.py I can't open file
[pylint] Context manager 'open' doesn't implement enter and exit. [not-context-manager]
here adding solution to ur problem, make your project structure like this.
add unifile/__init__.py file in the unifile itself not in other modules.
then unifile/open/_open.py file content
import yaml
class Open():
def __init__(self):
pass
def yml(self, file_path):
try:
with open(file_path, "r", encoding="utf-8") as yaml_conf:
yaml_file = yaml.safe_load(yaml_conf)
return yaml_file
except OSError:
print("Can't load yaml")
content of the unifile/__init__.py file
from .open._open import Open
in terminal run the program like this
Also, It is better to create a object element first then proceed ahead.
Two issues, two answers.
First, you should add an init file in unifile. With this, Python will understand that unifile is a package with a sub package.
Second, open is a built-in function and you overwrite it by calling your class open. Change your class name and it should work.
You are getting this error because unifile is not a package. There isn't any init.py file at the top level same as open and save. You also cannot call open.yml directly, because open is a class in package open, so either you will have to import open from open, create its instance and then call iml on that instance.
from open import open
a = open().yml('file.yml')
You are getting this error, because you are trying to override an existing keyword in Python open which you should strictly prohibit doing. So you should name your class anything except a reserved keyword.

How to choose an imported python file by user's command line argument

In a main python file, I import another python files, say their names are file1, file2, file3 and all of them have a function inside them named scrape(). I am trying to choose which file's scrape() will run according to user input, like the following:
python main.py file1
Here is the relevant part of my code:
import file1
import file2
import file3
fileName = sys.argv[1]
for func in ['%s.scrape' % fileName]:
meta, infos = func()
However, I get this error message:
Traceback (most recent call last):
File "main.py", line 50, in <module>
meta, infos = func()
TypeError: 'str' object is not callable
Note that it works when I use for func in [file1.scrape]: I just can't use user input as the imported file name. Can someone tell me how to do it?
You are trying to call func as a function, when it's really a string you built from the command-line argument.
For your purposes, as also mentioned in prashant's linked post, you might want to use something like the imp module.
Here's a quick example
import sys
import imp
# `imp.load_source` requires the full path to the module
# This will load the module provided as `user_selection`
# You can then either `import user_selection`, or use the `mod` to access the package internals directly
mod = imp.load_source("user_selection", "/<mypath>/site-packages/pytz/__init__.py")
# I'm using `user_selection` and `mod` instead of `pytz`
import user_selection
print(user_selection.all_timezones)
print(mod.all_timezones)
In your case, you might have to use imp.find_module to get the full path from just the name, or provide the full paths directly in the command line.
This should be a starting point
import sys
import imp
file_name = sys.argv[1]
f, filename, desc = imp.find_module(file_name, ['/path/where/modules/live'])
mod = imp.load_module("selected_module", f, filename, desc)
mod.scrape()

No attribute error in importing all module vs importing specific functions from module

When i wrote:
import urllib
fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
for line in fhand:
print(line.decode().strip())
The above function returns no attribute name 'request' found
but works when importing all the functions needed:
import urllib.request,urllib.parse,urllib.error
fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
for line in fhand:
print(line.decode().strip())
Any suggestions ?
From this answer: When you use an import statement it always searches the actual module path (and/or sys.modules); it doesn't make use of module objects in the local namespace that exist because of previous imports.
So if you want to use any object of the urllib, you need to type in the actual objects you want to use:
import urllib.request
You can also do that:
from urllib import request
fhand = request.urlopen('http://data.pr4e.org/romeo.txt')

Load pickled object in different file - Attribute error

I have some trouble with loading a pickled file in a module that is different from the module where I pickled the file. I am aware of the following thread: Unable to load files using pickle and multipile modules. I've tried the proposed solution of importing the class into the module where I am unpickling my file, but it keeps giving me the same error:
AttributeError: Can't get attribute 'Document' on <module '__main__' from ''>
The basic structure of what I am trying to do:
Util file that pickles and unpickles objects, utils.py:
import pickle
def save_document(doc):
from class_def import Document
write_file = open(file_path, 'wb')
pickle.dump(doc, write_file)
def load_document(file_path):
from class_def import Document
doc_file = open(file_path, 'rb')
return pickle.load(doc_file)
File where Document object is defined and the save util method is called, class_def.py:
import utils
class Document(object):
data = ""
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
File where the load util method is called, process.py:
import utils
if __name__ == '__main__':
utils.load_document(file_path)
Running process.py gives the mentioned AttributeError. If I import the class_def.py file into process.py and run its main method as mentioned in the original thread it works, but I want to be able to run these two modules separately, since the class_def file is a preprocessing step that takes quite some time. How could I solve this?
in your class_def.py file you have this code:
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
This means that doc will be a __main__.Document object, so when it is pickled it is expecting to be able to get a Document class from the main module, to fix this you need to use the definition of Document from a module called class_def meaning you would add an import here:
(in general you can just do from <own module name> import * right inside the if __name__ == "__main__")
if __name__ == '__main__':
from class_def import Document
# ^ so that it is using the Document class defined under the class_def module
doc = Document()
utils.save_document(doc)
that way it will need to run the class_def.py file twice, once as __main__ and once as class_def but it does mean that the data will be pickled as a class_def.Document object so loading it will retrieve the class from the correct place. Otherwise if you have a way of constructing one document object from another you can do something like this in utils.py:
def save_document(doc):
if doc.__class__.__module__ == "__main__":
from class_def import Document #get the class from the reference-able module
doc = Document(doc) #convert it to the class we are able to use
write_file = open(file_path, 'wb')
pickle.dump(doc, write_file)
Although usually I'd prefer the first way.
I had a similar problem and only just realized the differences between our implementations.
Your file structure:
util.py
define pickle functions
class_def.py
import util
define class
make instance
call save pickle
process.py
import util
load pickle
My mistake (using your file names) was first:
util_and_class.py
define class
define pickle funcs
make instance
call save pickle
process.py
import util_and_class
call load pickle << ERROR
What solved my pickle import problem:
util_and_class.py
define class
define pickle funcs
pickle_init.py
import util_and_class
make instance
call save pickle
process.py
call load pickle
This had the welcomed side effect that I didn't need to import the util_and_class file as it's baked into the pickle file. Calling the instance and saving the pickle in a separate file resolved the __name__ issue of "loading a pickled file in a module that is different from the module where I pickled the file."

Categories