If I have a function defined in my code lets call foo(), and I use the following code:
from mod1 import *
With mod1 containing a function also with the same name of foo() and call the foo() function, will this override my original definition of the function when it evaluates it?
As far as I know it will.
you would need to either rename you foo() function you have built OR change your module input to read
import mod1 and subsequently define any use of the foo() function from mod1 to mod1.foo()
Depends on where the function is:
def foo():
pass
from mod1 import *
foo() # here foo comes from mod1
# -------
# another interesting case
def foo():
from mod1 import *
foo() # this will also call foo from mod1
foo() # but this one is still the foo defined above.
# ---------
# The opposite
from mod1 import *
def foo():
pass
foo() # here foo is the one defined above
Anyway, from module import * is considered a VERY bad and error-prone practice. It is a kind of using namespace std;-like thing in C++. Avoid it as much as possible.
a.py
def foo():
print 'Hello A'
Test
>>> def foo():
... print 'Hello 1'
...
>>> foo()
Hello 1
>>> from a import *
>>> foo()
Hello A
>>> def foo():
... print 'Hello 2'
...
>>> foo()
Hello 2
I get the following:
file mod1.py contains
def foo():
print "hello foo"
and then i start python interpreter and do the following:
>>> def foo():
... print "hello world"
...
>>> from mod1 import *
>>> foo()
hello foo
>>>
So yes, it would override.
Unless you then do, a new
def foo():
print "new foo"
In which case it would print "new foo"
It depends on the relative order of the function definition and the import statement. Whichever is executed second will override the first.
Related
I am trying to get a list of all the functions in a class and then looping over them so they are all executed without having to type each one out. For example:
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
Then in another file
import Foo
import inspect
newfoo = Foo()
functions = [f for f in inspect.getmembers(Foo, predicate=inspect.isfunction)]
for f in functions:
newfoo.f[1]()
I am hoping to get:
foo
bar
But this gives the error
AttributeError: 'Foo' object has no attribute 'f'
Any ideas on how to execute this? Thanks in advance.
You can use getattr to call class method by name.
code:
import inspect
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
newfoo = Foo()
functions = [f for f in inspect.getmembers(Foo, predicate=inspect.isfunction)]
for f in functions:
getattr(newfoo, f[0])()
result:
bar
foo
You could even use it without the inspect module:
class Foo:
def foo():
print('foo')
def bar():
print('bar')
object_methods = [method_name for method_name in dir(Foo)
if not method_name.startswith("__") and
callable(getattr(Foo, method_name))]
print(object_methods)
This yields
['bar', 'foo']
Your code is almost correct. just change newfoo.f[1]() to f[1]() and it will work properly.
for f in functions:
f[1]()
When global variables are all on one script, things work smoothly.
def foo():
global x
x = 'bar'
goo()
def goo()
global x
print(x)
foo()
would print bar as expected.
However, it does not work when I have to import goo from another file, for example
file1.py
from file2 import goo
def foo():
global x
x = 'bar'
goo()
foo()
file2.py
def goo()
global x
print(x)
results in NameError. How can x be passed to the imported function like in the first case without passing it explicitly as an argument?
you have to set <module_name>.<variable_name> = 'bar' for it to work like so:
import file2
def foo():
file2.x = 'bar'
file2.goo()
foo()
file1 is the same
If we have something like:
foo.py
from bar import bar
class foo:
global black;
black = True;
bar = bar()
bar.speak()
f = foo()
bar.py
class bar:
def speak():
if black:
print "blaaack!"
else:
print "whitttte!"
when we run
python foo.py
we get
NameError: global name 'black' is not defined
What's the best practise for doing something like this?
Should I pass it in the method?
Have the bar class have a parent variable?
For context, in practise the black global is for a debugging step.
In Python, globals are specific to a module. So the global in your foo.py is not accessible in your bar.py--not the way you have it written at least.
If you want every instance of foo to have its own value of black, then use an instance variable as Ivelin has shown. If you want every instance of foo to share the same value of black use a class variable.
Using an instance variable:
# foo.py
from bar import bar
class foo:
# Python "constructor"..
def __init__(self):
# Define the instance variables
self.bar = bar()
# Make bar talk
self.bar.speak()
# Create a function for making this foo's bar speak whenever we want
def bar_speak(self):
self.bar.speak()
################################################################################
# bar.py
class bar:
# Python "constructor"..
def __init__(self):
# Define the instance variables
self.black = True
def speak(self):
if self.black:
print "blaaack!"
else:
print "whitttte!"
Playing with the code:
>>> f = foo()
blaaack!
>>> b = foo()
blaaack!
>>> b.bar.black = False
>>> b.bar_speak()
whitttte!
>>> f.bar_speak()
blaaack!
Using a class variable:
# foo.py
from bar import bar
class foo:
# Python "constructor"..
def __init__(self):
# Define the instance variables
self.bar = bar()
# Make bar talk
self.bar.speak()
# Create a function for making this foo's bar speak whenever we want
def bar_speak(self):
self.bar.speak()
################################################################################
# bar.py
class bar:
black = True
def speak():
if bar.black:
print "blaaack!"
else:
print "whitttte!"
Playing with the code:
>>> f = foo()
blaaack!
>>> b = foo()
blaaack!
>>> bar.black = False
>>> b.bar_speak()
whitttte!
>>> f.bar_speak()
whitttte!
Here is what I would do:
foo.py
from bar import bar
class foo:
bar = bar(black=True)
bar.speak()
f = foo()
bar.py
class bar:
def __init__(black):
self.black = black
def speak():
if self.black:
print "blaaack!"
else:
print "whitttte!”
How to mock a method that is not in the scope of a test?
or: How to mock a method that is not called directly?
In this case method baz
I'm using the Mock package from pypi
### tests
# ...
def test_method_a(self):
# how to mock method that is called from bar() ?
obj = foo.bar()
self.assertEqual(obj.get('x'), 12345)
### foo
# ...
def bar():
x = some_module.baz() # <- how to mock baz() ?
return x
Here is an example that should show you how it works:
from mock import patch
def baz():
return 'y'
def bar():
x = baz() # <- how to mock baz() ?
return x
def test():
with patch('__main__.baz') as baz_mock:
baz_mock.return_value = 'blah'
assert bar() == 'blah'
test()
IMHO this example better illustrates the common use case during unit testing.
The important part is the #patch decorator which effectively substitutes the side_effect function (this could also just be a value) for the function being patched. The tricky bit is often getting the full package path to the patched function. Notice how you must use '__main__.func' to reference the patched function.
The first test, test_func checks that the mocked value of the test is the original expected function value ('Hello World!'). The second test, test_mocked_func patches func to actually be the function object new_func, hence returning True. The third test illustrates substituting in values rather than a new function as the side_effect. In fact, since we made the substitution value an iterable (side_effect=['New String 1!', 'New String 2!', 3]), each time it runs, it will return a new value.
Warning: If you try to call your patched function more times than you have specified return values (3 in this case), you will get a StopIteration error since you didn't define enough return values in side_effect.
import unittest
from mock import patch # for Python 2.7
# from unittest.mock import patch # for Python 3.5
def func():
return 'Hello World!'
def newFunc():
return True
class TestFunc(unittest.TestCase):
def test_func(self):
self.assertEqual(func(), 'Hello World!')
#patch('__main__.func', side_effect=newFunc)
def test_mocked_func(self, *patches):
self.assertTrue(func())
#patch('__main__.func', side_effect=['New String 1!', 'New String 2!', 3])
def test_mocked_func_again(self, *patches):
self.assertEqual(func(), 'New String 1!')
self.assertEqual(func(), 'New String 2!')
self.assertEqual(func(), 3)
# func() # This breaks the test because we only specified a list of length 3 in our patch.
if __name__=='__main__':
unittest.main()
here's a sample code:
def foo():
def bar():
foobar = 'foobaz'
foobar = 'foobar'
print foobar
bar()
print foobar
foo()
I want to change variable foobar inside foo by function bar. The code above will not work, since foobar inside bar is in separate namespace with foobar in foo. A simple workaround would be making a global foobar and have both foo and bar can access it, but I hope there would be simpler workarounds.
On python 3.x you can use nonlocal and for python 2.x try using function attributes:
def foo():
def bar():
foo.foobar = 'foobaz' #change the function attribute
foo.foobar = 'foobar' #declare as function attribute
print foo.foobar
bar()
print foo.foobar
foo()
output:
foobar
foobaz
You are looking for the nonlocal keyword, which exists in 3.x.
def f():
x = None
def g():
nonlocal x
x = 1
If you are stuck in 2.x, you can do it by having a list or similar mutable data container and accessing that as a work around.
def f():
x = [None]
def g():
x[0] = 1
This works as variables do fall into scope, but won't leak out of scope. With mutable objects, we can change them inside the scope, and those changes propagate out.
Not possible in python 2.7. In python 3:
def foo():
def bar():
nonlocal foobar
foobar = 'foobaz'
foobar = 'foobar'
print foobar
bar()
print foobar
foo()
In 2.x, you can do:
def foo():
foobar = []
def bar():
foobar[0] = 'foobaz'
foobar[0] = 'foobar'
print foobar[0]
bar()
print foobar[0]
foo()
def foo():
def bar():
foobar = 'foobaz'
return foobar
foobar = 'foobar'
print foobar
foobar = bar()
print foobar
foo()
Even though functions are already first class objects in Python, you can create your own "functor" or function object something like this:
class Foo(object):
def bar(self):
self.foobar = 'foobaz'
def __call__(self):
self.foobar = 'foobar'
print self.foobar
self.bar()
print self.foobar
foo = Foo()
foo()