Can you please help me guys. I believe I've got pretty easy questions but don't want to stuff up with my assignment. I'm going to have Class in my module, this class will have few functions.
I just want to be sure it works alright and this is a not ugly code practice.
I.e. my first function test_info accepts one parameter test_code and returns something and the second function check_class accepts two parameter, one of them is called test_code as well
Can I use same argument name: test_code? Is it normal code practice?
def test_info (self, test_code):
my_test_code = test_code
#here we'll be using my_test_code to get info from txt file and return other info
def check_class (self, test_code, other_arg):
my_test_code = test_code
#here some code goes
Also is it fine to use my_test_code in both functions to get argument value or is it better to use different ones like my_test_code_g etc.
Many thanks
Yes you may.
The two variables test_code are defined only in the scope of their respective functions and therefore will not interfere with one another since the other functions lie outside their scope.
Same goes for my_test_code
Read online about variable scopes. Here is a good start
There is no technical reason to resolve this one way or another. But if the variables don't serve exactly the same purpose in both functions, it's confusing for a human reader if they have the same name.
Related
I am looking for a way in python to stop certain parts of the code inside a function but only when the output of the function is assigned to a variable. If the the function is run without any assignment then it should run all the inside of it.
Something like this:
def function():
print('a')
return ('a')
function()
A=function()
The first time that I call function() it should display a on the screen, while the second time nothing should print and only store value returned into A.
I have not tried anything since I am kind of new to Python, but I was imagining it would be something like the if __name__=='__main__': way of checking if a script is being used as a module or run directly.
I don't think such a behavior could be achieved in python, because within the scope of the function call, there is no indication what your will do with the returned value.
You will have to give an argument to the function that tells it to skip/stop with a default value to ease the call.
def call_and_skip(skip_instructions=False):
if not skip_instructions:
call_stuff_or_not()
call_everytime()
call_and_skip()
# will not skip inside instruction
a_variable = call_and_skip(skip_instructions=True)
# will skip inside instructions
As already mentionned in comments, what you're asking for is not technically possible - a function has (and cannot have) any knowledge of what the calling code will do with the return value.
For a simple case like your example snippet, the obvious solution is to just remove the print call from within the function and leave it out to the caller, ie:
def fun():
return 'a'
print(fun())
Now I assume your real code is a bit more complex than this so such a simple solution would not work. If that's the case, the solution is to split the original function into many distinct one and let the caller choose which part it wants to call. If you have a complex state (local variables) that need to be shared between the different parts, you can wrap the whole thing into a class, turning the sub functions into methods and storing those variables as instance attributes.
I have a file
outSimulation.py this file has a function called
outlet1 and inside this function there is a variable called data
I want to access this data variable from another program called main.py
I have tried it with absolute imports
from outSimulation import outlet1
values = outlet1.data()
but it doesnt work. Any help is appreciated.
You cannot* access a variable which is local to a function from outside the function.
If you want to access the value of data from a function which is called by outlet1(), you should pass data to that function.
If you want to access the value of data after outlet1() finishes running, you should return data (possibly along with other things) from outlet1().
Alternatively, you can make data a module-level variable. Assuming you assign something to data within outlet1(), you would make it a module-level variable using the global keyword,
def outlet1():
global data
# code
data = ...
# more code
but this tends to be less clean than the other methods.
There are other solutions if outlet1() is defined within a class, but your question suggests that's not the case so I won't get into that.
*Well... uh, never mind. There are some wacky things you can do for debugging, but you're better off not considering those for your purposes.
Functions are not classes, and are specifically designed so that you CAN'T do what you're trying to do. That's the whole basis of functional programming and the concepts behind encapsulation. Even if your function was a class, your code still wouldn't work because you're trying to call the variable as a function (by adding () to data).
Either create data as a global variable that can be referenced inside the function or have the function return a tuple with multiple items, including the original return value and the data variable (messy). You could also rewrite the function in an object-oriented way if that approach suits your problem domain, in which case your code above would make more sense.
I'm not an expert at python, so bear with me while I try to understand the nuances of variable scopes.
As a simple example that describes the problem I'm facing, say I have the following three files.
The first file is outside_code.py. Due to certain restrictions I cannot modify this file. It must be taken as is. It contains some code that runs an eval at some point (yes, I know that eval is the spawn of satan but that's a discussion for a later day). For example, let's say that it contains the following lines of code:
def eval_string(x):
return eval(x)
The second file is a set of user defined functions. Let's call it functions.py. It contains some unknown number of function definitions, for example, let's say that functions.py contains one function, defined below:
def foo(x):
print("Your number is {}!".format(x))
Now I write a third file, let's call it main.py. Which contains the following code:
import outside_code
from functions import *
outside_code.eval_string("foo(4)")
I import all of the function definitions from functions.py with a *, so they should be accessible by main.py without needing to do something like functions.foo(). I also import outside_code.py so I can access its core functionality, the code that contains an eval. Finally I call the function in outside_code.py, passing a string that is related to a function defined in functions.py.
In the simplified example, I want the code to print out "Your number is 4!". However, I get an error stating that 'foo' is not defined. This obviously means that the code in outside_code.py cannot access the same foo function that exists in main.py. So somehow I need to make foo accessible to it. Could anyone tell me exactly what the scope of foo currently is, and how I could extend it to cover the space that I actually want to use it in? What is the best way to solve my problem?
You'd have to add those names to the scope of outside_code. If outside_code is a regular Python module, you can do so directly:
import outside_code
import functions
for name in getattr(functions, '__all__', (n for n in vars(functions) if not n[0] == '_')):
setattr(outside_code, name, getattr(functions, name))
This takes all names functions exports (which you'd import with from functions import *) and adds a reference to the corresponding object to outside_code so that eval() inside outside_code.eval_string() can find them.
You could use the ast.parse() function to produce a parse tree from the expression before passing it to eval_function() and then extract all global names from the expression and only add those names to outside_code to limit the damage, so to speak, but you'd still be clobbering the other module namespace to make this work.
Mind you, this is almost as evil as using eval() in the first place, but it's your only choice if you can't tell eval() in that other module to take a namespace parameter. That's because by default, eval() uses the global namespace of the module it is run in as the namespace.
If, however, your eval_string() function actually accepts more parameters, look for a namespace or globals option. If that exists, the function probably looks more like this:
def eval_string(x, namespace=None):
return eval(x, globals=namespace)
after which you could just do:
outside_code.eval_string('foo(4)', vars(functions))
where vars(functions) gives you the namespace of the functions module.
foo has been imported into main.py; its scope is restricted to that file (and to the file where it was originally defined, of course). It does not exist within outside_code.py.
The real eval function accepts locals and globals dicts to allow you to add elements to the namespace of the evaluted code. But you can't do anything if your eval_string doesn't already pass those on.
The relevant documentation: https://docs.python.org/3.5/library/functions.html#eval
eval takes an optional dictionary mapping global names to values
eval('foo(4)', {'foo': foo})
Will do what you need. It is mapping the string 'foo' to the function object foo.
EDIT
Rereading your question, it looks like this won't work for you. My only other thought is to try
eval_str('eval("foo(4)", {"foo": lambda x: print("Your number is {}!".format(x))})')
But that's a very hackish solution and doesn't scale well to functions that don't fit in lambdas.
I'm trying to fix up a little program, but looks like I'm in a bit over my head. The whole code is too long to copy here, so I'm just gonna paste the problematic part.
def kontroll(self):
count=IntVar()
sisend=sisendivaartus.get()
print(count)
if count==1:
kast.delete(0.0,END)
sisend.delete(0.0,END)
count=0
else:
kast.delete(0.0,END)
if sisend=="õige" or sisend=="ÕIGE" or sisend=="Õige":
if oige==sonake:
if tahendus==" ":
kast.insert(END,"Tubli, õige!"+"\n"+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Tubli, õige!"+"\n"+str(oige)+"\n:"+str(tahendus))
count=1
#skoor+=1
#skoor=skoor+1
else:
if tahendus==" ":
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+":\n"+str(tahendus))
count=1
#vale=vale+1
#skoor=skoor-1
else:
if sisend==oige:
if tahendus==" ":
kast.insert(END,"Tubli, õige!\n"+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Tubli, õige!\n"+str(oige)+":\n"+str(tahendus))
count=1
#skoor=skoor+1
else:
if tahendus==" ":
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+"\n"+str(tahendus))
count=1
else:
kast.insert(END,"Kahjuks eksid. Õige on "+str(oige)+":\n"+str(tahendus))
count=1
#vale=vale+1
#skoor=skoor-1
#if skoor<0:
# skoor=0
Now the problem is that I have to add arguments to kontroll() but I don't know how to do that with 'self' being there. To be honest, I don't even understand why I need that 'self' there, 'cause I'm not using classes which usually use the 'self' argument... So anyway, I googled the error I recieved without having 'self' there and after adding 'self' it started working, but I can't add 'skoor' and 'vale' in brackets...
Right now I just start kontroll with nothing in brackets, like this: kontroll().
So how should I start the function and how should I add the arguments to it? I can't use global variables either, 'cause this 'skoor=skoor+1' messes everything up (can't have global variable on the left side of equals sign).
Thanks.
EDIT:
GUI part of my program looks like this:
raam=Tk()
raam.title("MÄNG")
raam.geometry("430x450")
valik=IntVar()
valik2=IntVar()
C2=Checkbutton(raam,text="f",variable=valik2,command=lambda:ok.config(state=ACTIVE)).place(x=5,y=10)
ok=Button(raam,text="Alusta!",command=alusta,state=DISABLED)
ok.place(x=230,y=20,width=80)
C1=Checkbutton(raam,text="š",variable=valik,command=lambda:ok.config(state=ACTIVE)).place(x=5,y=30)
sisendivaartus=StringVar()
sisend=Entry(raam,textvariable=sisendivaartus)
sisend.place(x=10,y=250,width=200)
sisend.bind("<Return>",kontroll(skoor,vale))
credit=Label(raam,text="2013",font=("Verdana","7"))
credit.place(x=0,y=430)
score=Label(raam,text="Skoor:",font=("Verdana","7"))
score.place(x=380,y=430)
nupp=Button(raam,text="Seaded",command=seaded)
nupp.config()
nupp.place(x=330,y=20,width=80)
kast=Text(raam,wrap=WORD,font=("Verdana",10))
kast.config()
app=App(raam)
kast.place(x=10,y=60,width=400,height=180)
raam.mainloop()
For Henry's suggestion (how to use the function when not in class), I start getting different errors that have no basis, for example "NameError: global name 'oige' is not defined". Despite what the error says, global name 'oige' is defined and works fine without arguments. If I replace 'skoor' and 'vale' in the functions definition with just 'self' and recall it without any arguments, everything works just fine. I guess this is kind of hard to understand without seeing the whole piece, so I uploaded it here, if anyone has a minute.
PS. what I said earlier about having 0 classes in my code - that has changed since I constantly keep working on this. Also please keep in mind that this is a beta version of a beta, so many things are not supposed to work yet.
(For trivia: it tests and trains person's capabilities in Estonian orthography)
Writing Your Function
It's very easy to add more arguments to a function; simply change your function definition to
def kontroll(self, skoor, vale):
# Your code here.
Then skoor and vale become variable names local to the kontroll function and you can use them like any other variable.
As to why you need self in the function definition, that's because (presumably) this method is actually an instance method of some class you've defined. Instance methods always receive the object they're bound to as their first argument. This argument is called self, which is why you have to have an argument reserved for it. See this question for a more complete explanation.
If this is not actually an instance method of some class, mind you, then you don't actually need self. And generally speaking, if the method doesn't need a reference to a specific object instance, then there's no reason to make it an instance method!
Calling Your Function
Calling your function is just as simple, but it depends on the answer to the other question: is this actually an instance method? If it's defined inside a class (which it sounds like it is) then you need to do something like the following:
class C(object):
def kontroll(self, skoor, vale):
pass # Your code goes here.
c = C() # Create an instance of the class!
c.kontroll(skoor, vale) # The instance (c) is automatically passed to the method.
If, on the other hand, your function is not defined inside a class, your code should look like this:
def kontroll(skoor, vale):
pass # Your code goes here.
kontroll(skoor, vale)
You need self because this is almost certainly a method of a class, and you need to pass the object to the method when it is called. Self is just a convention, technically you can use some other name for this just as easily. That being said, it seems like you need to do some reading about classes in python and really try to understand the way an object instance works. I recommend starting with the docs:
http://docs.python.org/2/tutorial/classes.html
There appear to be a lot of globals in your code snippet that should probably be class variables, and you really need to understand how things like the __init__ method work before going to deep into this.
is it possible to add a local varible to a function, just before calling it ? if yes how ?
EDIT:REASON
i noticed that all my views in django are using
render_to_response(template_name,locals())
now i created a middleware and i wanted to add one more local variable using the
def process_view():
method of it .so that i don't have to modify the views .
The local scope for a function does not exist until the function is called, so it's not possible to do this. You could do this for a closure, but the next person to have to maintain the code would hunt you down and kill you.
Although I also think it is pretty useless, I thought that you may enclose the function in either a 'with' statement or another function, like the code below. Of course, this approach can be accomplished directly within the function of interest. In fact, you are adding the local variable 'during' the function declaration. See if this fits your needs!
#!/usr/bin/python
def my_funct(_local):
"""My function of interest
"""
print "Local argument was %s" % str(_local)
return "Finished"
def localize(fct, local_var):
"""
"""
return fct(_local = local_var)
## Use function to 'localize' variable
localize(my_funct, local_var="LOCAL_VARIABLE")
## Same effect without supplementary function :
my_funct(_local="LOCAL_VARIABLE")
try:
print local_var
except:
print "No such global variable"
Just some thoughts :)
Cheers
So if you’re one of those lazy
programmers and you like keeping code
particularly concise, you can take
advantage of a built-in Python
function called locals(). It returns a
dictionary mapping all local variable
names to their values, where “local”
means all variables that have been
defined within the current scope.
source
It is a trick in order to not have to explicitly list all of the variables you need to pass in to the function. In this case, you need to explicitly state a variable to pass in. Therefore, you should not be using locals() in the calls you are making in your middle-ware, as the trick was not designed to be used like that.
i mangaged to do that using decorators.