Problem grabbing parameters using execfile within a class - python

I have a problem similar to the first problem in this question, which as far as I can see went unanswered.
I have a file "config.py" which contains a lot of parameters to be used by a class (this config.py file will change), however I can't get these to propagate into the class via execfile.
In an example piece of code:
class Class():
def __init__(self):
execfile("config.py")
print x
# config.py
x = "foo"
>>> t = Class()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NameError: global name 'x' is not defined
Any help welcome, or any better methods of retrieving parameters from a file to be used in a class.
Many Thanks.

I don't get what you're trying to do (but i don't like it, and this is just me) but to fix your problem do (test in python2.6):
class Class():
def __init__(self):
execfile('config.py', locals()) # Not recommanded, maybe you want globals().
print x
But from the doc:
Note
The default locals act as described
for function locals() below:
modifications to the default locals
dictionary should not be attempted.
Pass an explicit locals dictionary if
you need to see effects of the code on
locals after function execfile()
returns. execfile() cannot be used
reliably to modify a function’s
locals.
and about :
Any help welcome, or any better
methods of retrieving parameters from
a file to be used in a class.
You can use import.

Even though it might be convenient to keep configuration settings in a Python file I would recommend against it. I think it opens up a whole set of problems that you don't really want to have do deal with. Anything could be placed in your configuration file, including malicious code.
I would use either the json module or the ConfigParser module to hold my configuration.
If you have trouble choosing between those two I would recommend the json module. Json is a simple yet flexible format for structured data.

Related

Why doesn't this simple Python script run?

I am writing a large program where I need to pass data/variables between functions. Note: I'm a hobbyist and OOP is out of my grasp, so just looking for a non-OOP answer!
I'm using functions to try and make the script modular and avoid having one long messy script. But the program uses a dataframe and lots of different variables which many of the functions will need to access. I don't want to specify every single variable in every function call so would like to be able to access global variables from individual functions. I can do this when the def function(): is in the same script, but I am running into a problem when I try and call global variables when importing a function from a script. Simple reprex:
from test_func import p_func
a = "yes!"
p_func()
calling p_func() from test_func.py
def p_func():
global a
print(a)
generates the error:
Traceback (most recent call last):
File "test.py", line 5, in <module>
p_func()
File "test_func.py", line 5, in p_func
print(a)
NameError: name 'a' is not defined
What am I missing?
You need to change your import line to be:
from test_func import p_func, a
Variables are imported from other modules the same way that functions are.
That said. This is really, really a bad idea as others above has said. Your best off putting all your variables into a single data structure of some sort

AttributeError: 'builtin_function_or_method' object has no attribute 'get_valid_locations_'

I start with the assumption that I have already looked at many other posts related to the "builtin_function_or_method" error, but I have not found a solution to my problem. I really hope that someone has a moment to read because I write this post out of exhaustion.
To summarize: the following piece of code invokes the "get_valid_locations_" function
valid_locations = eval.get_valid_locations_(board)
The method I call is a function of the Evaluate class that I have previously imported in this way (I attach both how I imported the file and how I instantiated the object)
from Utilities import evaluate
eval = evaluate.Evaluate()
While the function is as follows
def get_valid_locations_(self, board):
valid_locations = []
for col in range(NUMS_COL):
if eval.is_valid_location(board, col):
valid_locations.append(col)
return valid_locations
I cannot understand what generates the error. It seems to me that the assignment and the way in which I import the class is correct, also because in the Evaluate class there are other functions that do not generate errors. So the problem I think is restricted to either the function or how it is invoked. Unless the Python compiler sees the method. I also tried to add the _ to the end of the function name but nothing.
I hope someone can help me or have some advice on how to better structure the files for projects. Thanks a lot in advance and have a nice day.
In this line that's failing:
valid_locations = eval.get_valid_locations_(board)
It sees eval as the standard Python builtin function eval. Wherever you defined it like this:
eval = evaluate.Evaluate()
The first line is not seeing that definition.
First of all, choose a different name that isn't a Python builtin to reduce confusion.
Then make sure that your use of the object eval has the correct value. If you defined it globally in a module, then from some_module import eval. Or you could pass it as an argument to a function where eval.get_valid_locations_(board) is called.
Your definition of get_valid_locations_ has a similar problem where it calls eval.is_valid_location(board, col). If get_valid_locations_ and is_valid_location are both methods of the class Evaluate, then you should call self.is_valid_location instead. Not all instances of Evaluate should necessarily be called eval, nor should they have to be defined in the same file as the class.
you created an eval object, and then trying to call get_valid_locations_ function on it.
valid_locations = eval.get_valid_locations_(board)
this is what generates the error. eval object has no get_valid_locations_ function.

dynamically adding a function to existing imported module

This maybe a very naive question and perhaps it's best asked with an example:
module1.py
import module2
def new_func():
print(var_string)
module2.new_func = new_func
module2.func()
module2.new_func()
module2.py
var_string = "i'm the global string!"
def func():
print(var_string)
result
> python module1.py
i'm the global string!
Traceback (most recent call last):
File "module1.py", line 8, in <module>
module2.new_func()
File "module1.py", line 4, in new_func
print(var_string)
NameError: name 'var_string' is not defined
So my question is this:
Is it possible to insert a function into a module and have it's global namespace update accordingly?
Related: global variable defined in main script can't be accessed by a function defined in a different module
Note that I am aware that sharing global variables is a bad idea and I'm also aware that a configuration module would be a good compromise to that but also please note that this is not what I am trying to achieve.
You may think it is useful, but very little python code is written this way and I think most python programmers would be confused with code that does this. Modifying a module after it's been imported (monkeypatching) is usually looked down upon because it's very easy to do the wrong thing and cause strange bugs.
You made an analogy comparing it to overriding / extending methods on a class, but if this is really what you want to do, why not just use a class? The features of classes make it much safer and easier to do this kind of thing.
Your code will work if you do this:
from module2 import var_string
#or..
from module2 import *
But I'm not sure if that's the solution you're looking for. Either way, I personally wouldn't try to make this code work, it's fighting against the way python code is normally written. If you have a practical example of code that you think would be improved by dynamically modifying modules, I would like to see it. It's a little hard to see the benefit with the example code you gave.
I'm not understand what you want, and what this string must do "module2.new_func = new_func", because you dont have the function new_funcin module2.
But if you want to reseting variable in each modules, you cant use like this :
Module1 :
import module2
def new_func():
print(var_string)
new_class=module2.MyStuff()
var_string=new_class.func()
new_func()
Module2:
class MyStuff:
def __init__(self):
self.var_string = "i'm the global string!"
def func(self):
print(self.var_string)
return self.var_string

Calling a function from a dictionary, dictionary in imported settings file

So I have a dictionary with a bunch of names that I use to call functions. It works fine, but I prefer to put it in my settings file. If I do so, though, I will get errors from the settings file saying that there are no functions by that name(even though I'm not calling them at the time). Any workarounds?
def callfunct(id, time):
#stuff here
def callotherfunct(id, time):
#stuff here
dict = {"blah blah": callfunct, "blah blah blah": callfunct, "otherblah": callotherfunct}
dict[str(nameid)](id, time)
Hope this makes sense. Also open to other ideas, but basically I have about 50 iterations of these definitions and unique names that are passed by nameid that need to call specific functions, so that's why I do it the way I do, so that I can add new names quickly. It would obviously be even quicker if I could get the dictionary into the settings file seamlessly as well.
If you try
def f_one(id, time):
pass
def f_two(id, time):
pass
d = {"blah blah":"f_one", "blah blah blah":"f_one", "otherblah","f_two"
locals()[d[str(nameid)]](id, time)
(replacing the dictionary initialization with just loading the config file with the string name of the functions you want to call), does that work?
If not, there needs to be a little more info: What does the config file look like, and how are you loading it?
I'm guessing the reason that the config file part isn't working is that you're trying to reference the functions directly from the config file, which shouldn't work. This is using whatever's stored in the config file and looking it up in the locals() dictionary (if you're in a function, you'll have to use globals() instead)
You could initialise the dictionary with the looked up function only when you attempt to access it:
d = {}
d.setdefault('func1', globals()['func1'])()

Is it possible to import to the global scope from inside a function (Python)?

I am trying to import a module from inside a function and have it be available to my whole file the same way it would be if I imported outside any functions and before all the other code. The reason it is in a function is because I don't have much control over the structure of the script. Is this possible without resorting to things like hacking __builtin__ or passing what I need all around my code?
How about something like globals()["os"] = __import__("os")?
I guess this could be wrapped in a generic function if you wanted since the module name is a string.
Seeing your new comments, I want to emphasize that this sounds unnecessary. You're actually modifying the script more by importing within a function than by importing at the top of the script in the normal way. Still, in the spirit of answering the question asked, I'm leaving my previous answer.
I'm honestly not certain this is the correct way to do this, but a quick check confirms that if you declare the module name as global within the function before importing, it is imported into the global namespace.
>>> def import_re():
... global re
... import re
...
>>> re
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 're' is not defined
>>> import_re()
>>> re
<module 're' from '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.pyc'>
Don't do this unless you really have to -- and then write it in big red letters, so to speak.

Categories