Is there a clean way to reuse code blocks in python classes to avoid having to retype the same code? For example lets say at the beginning of 2 different functions there is the same lines of code required to set up the function (where it is desired to keep the set up variables locally in the function).
def func1(path, x, y):
img = load_img('path')
img.normalize()
foo = Foo(x)
bar = Bar(y)
**rest of the function (using img, foo and bar)
def func2(path, x, y):
img = load_img('path')
img.normalize()
foo = Foo(x)
bar = Bar(y)
**different code here to func 1
Is there a standard best practice to set up the local variables to avoid code repetition? Like a function which can set local variables (maybe using nonlocal)? I know I could technically do the entire set up in a single function, however with a lot of input and output variables it might get a bit messy. I just wanted to see if there was a more elegant way to approach this, as ideally I'd just be able to call some arbitrary function which sets up the entire local space.
*Also just noting, I am aware I can wrap all the code in a class, turn the functions into methods and have shared attributes, however I don't think that's quite the right solution for this situation.
Put the common code in another function that returns the values.
def common(path, x, y):
img = load_img(path)
img.normalize
return img, Foo(x), Bar(y)
def func1(path, x, y):
img, foo, bar = common(path, x, y)
# different code
def func2(path, x, y):
img, foo, bar = common(path, x, y)
# different code
You might also consider using a decorator.
Related
I have a small project for my numerical analysis class where I have to evaluate several functions using different methods so that we can compare the performance and efficiency of these methods. While most of my code runs fine, one of the function we must evaluate is the cube root of x. Since python utilizes the principal root, this causes the methods to diverge. I want to be able to use one function name so that I don't have to copy paste everything when I have to use the cube root function. Is there a way to have a function be redefined at runtime? I do not have any classes implemented so I do not want introduce a class if possible. Thanks.
EDIT:
my main function is this:
def main():
global func, derv
func = 'pow(x,2)*sin(x)'
derv = '2*x*sin(x)+pow(x,2)*cos(x)'
print('evaluating x^2sin(x): ')
newton(-0.2,10**-4,20)
bisection(-0.9,1,10**-4,20)
fixed(-0.2,10**-4,20)
func = 'pow(x,2)*sin(x)-x'
derv = '2*x*sin(x)+pow(x,2)*cos(x)-1'
print('evaluating x^2sin(x)-x: ')
newton(-0.2,10**-4,20)
bisection(-0.9,1,10**-4,20)
fixed(-0.2,10**-4,20)
func = 'pow(x,1/3'
derv = '(1/3)*pow(x,(-2/3)'
print('evaluating cuberoot(x): ')
newton(-0.2,10**-4,20)
bisection(-0.9,1,10**-4,20)
fixed(-0.2,10**-4,20)
and my function/derivate functions are:
def function(x):
y = eval(func)
return y
def function(x):
y = eval(func)
return y
the function and derivate functions are used in other functions to evaluate numbers for the numerical methods i'm using. For the cube root function, since the methods will have the values bouncing between negative and positive numbers, I would have to create a function or something in order to return a valid value.
Let's say I have a python function, where x and y are relatively large objects (lists, NumPy matrices, etc.):
def myfun(x):
y=some complicated function of x
return y
If in an interactive session the user calls this as:
myfun(5)
The call is basically useless, since y is lost. Let's also suppose the function takes a while to run. Is there a way to retrieve the answer, so the user doesn't have to re-run, i.e. answer=myfun(5)? Alternatively, what is a good (pythonic) way to write the function to make it 'fool-proof' for this scenario? Some not-so-great options are:
Require a parameter that stores the value, e.g.
def myfun(x,y):
y = some complicated function of x
return y
Or maybe:
def myfun(x):
y = some complicated function of x
global temp
temp = y
return y
In the latter case, if a user then mistakenly called myfun(5), there's the option of y=temp to get the answer back.. but using global just seems wrong.
y=_
assuming you are in the interactive python console. _ is magic that holds the last "result"
A bit of a general question that I cannot find the solution for,
I currently have two functions
def func1(*args, **kwargs):
...
return a,b
and
def func2(x,y):
...
return variables
I would like my code to evaluate
variables = func2(func1())
Which python does not accept as it says func2 requires two arguments when only one is given. My current solution is doing an intermediate dummy redefinition but makes my code extremely cluttered (my "func1" has an output of many parameters).
Is there an elegant solution to this?
def func1():
return 10, 20
def func2(x, y):
return x + y
results = func2(*func1())
print results
--output:--
30
A function can only return one thing, so func1() actually returns the tuple (10, 20). In order to get two things, you need to explode the tuple with *.
I've been trying to make a soccer game using Python. Most of the problems I've run into I've been able to find a way around. However, I'm getting stuck on the error "global name '---' not defined", referring to a method name. From what I've seen, the problem deals with trying to call a method from a method. Since pasting my code would take too much time explaining what was going on, I wrote a very basic example of the problem:
class example():
def doMath(x,y):
z = x + y
z = square(z)
return z
def square(z):
z = z * z
return z
print doMath(5,4)
This is in no way meant to be a program worth writing, nor is it the smart way of doing that calculation... It just imitates the problem I'm having. This code will not work, because the method "doMath" doesn't know the method "square" exists. I've seen this fixed by making the square method a submethod (I don't know what it's called, it's just indented under the primary method). However, that is not viable in my soccer code since I'd be having multiple methods calling it. I've seen similar questions to this, but the answers still don't fit my code. A global function seems like it would be what I'm looking for, but it typically leads to an error of something not existing. I could just add a bunch of instructions to the main, but that's alot of work and lines of code that I'd prefer not to have to add - it would make it pretty ugly.
So the main question is... how can I get the doMath method to call the square method without having to combine them.
While we're at it... I've been calling these methods rather than functions... am I correct on that?
As others have noted, you need to use self, and you need to call your methods correctly, with an instance, for example:
#!/usr/bin/python
class example():
def doMath(self, x, y):
z = x + y
z = self.square(z)
return z
def square(self, z):
z = z * z
return z
p = example()
print p.doMath(5,4)
outputs:
paul#local:~/src/python$ ./square.py
81
paul#local:~/src/python$
Clearly, in this particular case there's no advantage to these methods being in a class at all, and you could more easily do:
#!/usr/bin/python
def square(z):
return z * z
def doMath(x, y):
return square(x + y)
print doMath(5,4)
While we're at it... I've been calling these methods rather than functions... am I correct on that?
method -> routine that is a member of a class.
function -> routine that returns a result (compare with mathematical function)
procedure -> routine that does not return a result
member -> part of a class or struct (either a member variable or a member function etc)
Procedures are odd in python because even though a procedure does not return anything you can still assign its result to a variable.
The result in this case is None see here: Python procedure return values
If doMath and square are part of a class, they both should have another parameter called self. Methods calls take place on this self parameter. For example:
def doMath(self, x, y):
z = x + y
z = self.square(z)
return z
class example():
def doMath(self,x,y):
z = x + y
z = self.square(z)
return z
def square(self,z):
z = z * z
return z
def p(self):
print self.doMath(5,4)
e=example()
e.p()
I have a large function in my script that contains the bulk of the logic of my program.
At one point, it used to span ~100 lines which I then tried to refactor into multiple smaller functions. However, I had many local variables that were eventually being modified in the smaller functions, and I needed some way to keep track of them in the scope of the larger function.
For instance, it looked like
def large_func():
x = 5
... 100 lines ...
to
def large_func():
x = 6
small_func_that_will_increment_x()
small_func()
....
What is a pythonic way to handle this?
The two approaches I can think of are:
1) global variables --- will probably get messy as I have many variables
2) using a dict to keep track of them like
tracker = {
'field1' : 5
'field2' : 4
}
and make modifications on the dict instead.
Is there a different way to do this that I might have overlooked?
Without more information, it's hard to know whether this is appropriate or not, but…
An object is a namespace. In particular, you can turn each of those local variables into attributes on an object. For example:
class LargeThing(object):
def __init__(self):
self.x = 6
def large_func(self):
self.small_func_that_will_increment_x()
self.small_func()
# ...
def small_func_that_will_increment_x(self):
self.x += 1
Whether the self.x = 6 belongs in __init__ or at the start of large_func, or whether this is even a good idea, depends on what all those variables actually mean, and how they fit together.
Closures will work here:
def large_func()
x = 6
def func_that_uses_x():
print x
def func_that_modifies_x():
nonlocal x # python3 only
x += 1
func_that_uses_x()
func_that_modifies_x()
Another tip - make use of Python's ability to return multiple values. If you have a function that modifies two variables, do something like this:
def modifies_two_vars(a, b, c, d):
return a+b, c+d
x, y = modifies_two_vars(x, y, z, w)
One alternative could be:
def small_func_that_will_return_new_x(old_x):
return old_x + 1
def large_func():
x = small_func_that_will_return_new_x(6)
instead of:
def large_func():
x = 6
small_func_that_will_increment_x()
Object composition. Create small objects that hold state, and then feed them as initializers an object that manages them. See Global State and Singletons
"Build the door knob, which you use to build the door, which you use to construct the house. Not the other way around"