class declaration in exec inits class, but functions don't work - python

I am going to attach two blocks of code, the first is the main code that is ran the second is the testClass file containing a sample class for testing purposes. To understand what's going on it's probably easiest to run the code on your own. When I call sC.cls.print2() it says that the self parameter is unfulfilled. Normally when working with classes, self (in this case) would be sC.cls and you wouldn't have to pass it as a parameter. Any advice is greatly appreciated on why this is occuring, I think it's something to do with exec's scope but even if I run this function in exec it gives the same error and I can't figure out a way around it. If you'd like any more info please just ask!
import testClass
def main():
inst = testClass.myClass()
classInfo = str(type(inst)).split()[1].split("'")[1].split('.')
print(classInfo)
class StoreClass:
def __init__(self):
pass
exec('from {} import {}'.format(classInfo[0], classInfo[1]))
sC = StoreClass()
exec('sC.cls = {}'.format(classInfo[1]))
print(sC.cls)
sC.cls.print2()
if __name__ == '__main__':
main()
class myClass:
def printSomething(self):
print('hello')
def print2(self):
print('hi')

Related

passing self with other argument on function call python

I have a little problem, I have my code below.
I want to call the "speak" function with two arguments inside the main() class.
When I call speak it says that self its not defined, and i don't know how to make it work...
Any ideas?
class main():
def blueon(self):
print("teste")
def speak(self,fala):
self.blueon
print(fala)
speak("testeaaaaa")
Try something like this.
Comments explain changes
class Main: # Class name capitalized and no parenthesis if the class has no base classs
def __init__(self): # class constructor. Initialize here your variables
pass
# if you have a function that doesn't use self, you can declare it static
#staticmethod
def blueon():
print("teste")
def speak(self, fala):
self.blueon() # added missing parenthesis
print(fala)
if __name__ == "__main__": # add this so you can later import your class as a library without executing your test code
m = Main() # instantiate the class
m.speak("testeaaaaa") # call the speak method
You run speak() in wrong way.
First you have to create instance of class m = main() and later use m.speak("text").
And you have to do with different indetation.
BTW: There is good rule to use CamelCaseName for classes - class Main(): - it helps to recognize class in code, and it allows to do main = Main().
More in PEP 8 -- Style Guide for Python Code
# --- classes ---
class Main():
def blueon(self):
print("teste")
def speak(self, fala):
self.blueon() # you forgot `()
print(fala)
# --- main ---
main = Main()
main.speak("testeaaaaa")

Passing class objects to another class method Python

I am trying to understand where my mistake lies and I was hoping you could please help me.
I have this code:
import copy
class FooInd():
def __init__(self):
self.a=1
class Planning():
def foo(self,pop):
print(pop.a)
def main():
ind=FooInd()
Planning.foo(copy.deepcopy(ind))
if __name__ == "__main__":
Planning.main()
However I keep receiving this error:
Planning.foo(copy.deepcopy(ind))
TypeError: foo() missing 1 required positional argument: 'pop'
I believe that the mistake is not in the foo method definition, but in my class initiation of the FooInd, however I have checked the Python documentation for classes and I could not find a solution.
Does anyone have a clue of what could I try or where can I check?
Many thanks in advance!
You call Planning.foo on the class, not an instance of the class. You provided the second argument it requires, but not the self argument.
You have two choices:
Construct a Planning instance to call foo on:
def main():
ind=FooInd()
Planning().foo(copy.deepcopy(ind))
# ^^ Makes simple instance to call on
Make foo a classmethod or staticmethod that doesn't require an instance for self:
class Planning():
#staticmethod # Doesn't need self at all
def foo(pop):
print(pop.a)
I think you meant to instantiate Planning before calling methods on it:
import copy
class FooInd():
def __init__(self):
self.a = 1
class Planning():
def foo(self, pop):
print(pop.a)
def main(self):
ind = FooInd()
self.foo(copy.deepcopy(ind))
if __name__ == "__main__":
p = Planning()
p.main()
Output:
1

How to verify when an unknown object created by the code under test was called as expected (pytest) (unittest)

I have some code that creates instances from a list of classes that is passed to it. This cannot change as the list of classes passed to it has been designed to be dynamic and chosen at runtime through configuration files). Initialising those classes must be done by the code under test as it depends on factors only the code under test knows how to control (i.e. it will set specific initialisation args). I've tested the code quite extensively through running it and manually trawling through reams of output. Obviously I'm at the point where I need to add some proper unittests as I've proven my concept to myself. The following example demonstrates what I am trying to test:
I would like to test the run method of the Foo class defined below:
# foo.py
class Foo:
def __init__(self, stuff):
self._stuff = stuff
def run():
for thing in self._stuff:
stuff = stuff()
stuff.run()
Where one (or more) files would contain the class definitions for stuff to run, for example:
# classes.py
class Abc:
def run(self):
print("Abc.run()", self)
class Ced:
def run(self):
print("Ced.run()", self)
class Def:
def run(self):
print("Def.run()", self)
And finally, an example of how it would tie together:
>>> from foo import Foo
>>> from classes import Abc, Ced, Def
>>> f = Foo([Abc, Ced, Def])
>>> f.run()
Abc.run() <__main__.Abc object at 0x7f7469f9f9a0>
Ced.run() <__main__.Abc object at 0x7f7469f9f9a1>
Def.run() <__main__.Abc object at 0x7f7469f9f9a2>
Where the list of stuff to run defines the object classes (NOT instances), as the instances only have a short lifespan; they're created by Foo.run() and die when (or rather, sometime soon after) the function completes. However, I'm finding it very tricky to come up with a clear method to test this code.
I want to prove that the run method of each of the classes in the list of stuff to run was called. However, from the test, I do not have visibility on the Abc instance which the run method creates, therefore, how can it be verified? I can't patch the import as the code under test does not explicitly import the class (after all, it doesn't care what class it is). For example:
# test.py
from foo import Foo
class FakeStuff:
def run(self):
self.run_called = True
def test_foo_runs_all_stuff():
under_test = Foo([FakeStuff])
under_test.run()
# How to verify that FakeStuff.run() was called?
assert <SOMETHING>.run_called, "FakeStuff.run() was not called"
It seems that you correctly realise that you can pass anything into Foo(), so you should be able to log something in FakeStuff.run():
class Foo:
def __init__(self, stuff):
self._stuff = stuff
def run(self):
for thing in self._stuff:
stuff = thing()
stuff.run()
class FakeStuff:
run_called = 0
def run(self):
FakeStuff.run_called += 1
def test_foo_runs_all_stuff():
under_test = Foo([FakeStuff, FakeStuff])
under_test.run()
# How to verify that FakeStuff.run() was called?
assert FakeStuff.run_called == 2, "FakeStuff.run() was not called"
Note that I have modified your original Foo to what I think you meant. Please correct me if I'm wrong.

Python - Function isn't 'Global' and so can't be called within Threading Class

So, first off here's my code:
import threading
print "Press Escape to Quit"
class threadOne(threading.Thread): #I don't understand this or the next line
def run(self):
setup()
def setup():
print 'hello world - this is threadOne'
class threadTwo(threading.Thread):
def run(self):
print 'ran'
threadOne().start()
threadTwo().start()
So, the problem is that within my class 'threadOne' the run function runs (as that is called by the threading module) but from there I can not called any other functions. That includes if I make more functions beneath the setup() function. For example above, in my run(self) function I try and call setup() and get 'NameError: global name 'setup' is not defined'.
Does anybody have any ideas or can they explain this to me?
Sam
setup is a method of your Thread instance. Therefore, you call it with self.setup() rather than setup(). The latter is trying to call a global function named setup which does not exist.
Since setup() is an instance method, it must accept self as its first parameter as well.
I assume you meant to do the following:
class threadOne(threading.Thread): #I don't understand this or the next line
def run(self):
self.setup()
def setup(self):
print 'hello world - this is threadOne'

declarations within python class equivalent to _init_?

I was wondering if the declarations put at the top of the python class are equivalent to statements in __init__? For example
import sys
class bla():
print 'not init'
def __init__(self):
print 'init'
def whatever(self):
print 'whatever'
def main():
b=bla()
b.whatever()
return 0
if __name__ == '__main__':
sys.exit( main() )
The output is:
not init
init
whatever
As a sidenote, right now I also get:
Fatal Python error: PyImport_GetModuleDict: no module dictionary!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Any ideas on why this is? Thank you in advance!
No, it's not equivalent. The statement print 'not init' is run while the class bla is being defined, even before you instantiate an object of type bla.
>>> class bla():
... print 'not init'
... def __init__(self):
... print 'init'
not init
>>> b = bla()
init
They aren't exactly the same, because if you do c=bla() afterwards it will only print init
Also, if you reduce your main() to just return 0 it still prints the not init.
Declarations such as that are for the whole class. If print was a variable assignment rather a print statement then the variable would be a class variable. This means that rather than each object of the class having its own, there is only one of the variable for the whole class.
They are not equivalent. Your print statement outside the init method is only called once, when he class is defined. For example, if I were to modify your main() routine to be the following:
def main():
b=bla()
b.whatever()
c = bla()
c.whatever()
return 0
I get the following output:
not init
init
whatever
init
whatever
The not init print statement executes once, when the class is being defined.

Categories

Resources