I had generated a few values and had populated them into a spreadsheet using xlsxwriter. This is how I did it:
class main1():
.
.
.
.
def fun1():
workbook = xlsxwriter.Workbook(self.Output_fold+'Test'+time.strftime("%H_%M_%S_%d_%m_%Y")+'.xlsx')
worksheet_A = workbook.add_worksheet('Sheet_A')
.
.
worksheet_A.write(row,col,<val>)
.
.
workbook.close()
Now, since I had to make multiple writes, and added more complex logic, I decided to have another function introduced fun2 which would write the values accordingly. The new logic requires generating values in fun1 as well as fun2 (by calling another function fun3). So, I decided to replace variables workbook etc with self.workbook and likewise. My modified script looks like this :
main_file.py
import xlsxwriter
import libex
import os
import time
import sys
import string
class main_cls():
def __init__(self):
self.i=0
self.t1=""
self.t2=""
pwd=os.getcwd().split('\\')
base='\\'.join(pwd[0:len(pwd)-1])+'\\'
print base
self.Output_fold=base+"Output\\"
self.Input_fold=base+"Input\\"
self.workbook=xlsxwriter.Workbook(self.Output_fold+'Test_'+time.strftime("%H_%M_%S_%d_%m_%Y")+'.xlsx')
self.worksheet_A = self.workbook.add_worksheet('Sheet_A')
self.worksheet_A.write(self.i,self.i,"Text 1")
self.worksheet_A.write(self.i,self.i+1,"Text 2")
self.i+=1
def fun1(self):
self.t1="1"
self.t2="2"
self.worksheet_A.write(self.i,self.i,self.t1)
self.worksheet_A.write(self.i,self.i+1,self.t2)
self.i+=1
self.eg=libex.exlib()
self.t1=self.eg.gen(0)
self.t2=self.eg.gen(0)
self.fun2()
self.workbook.close()
def fun2(self):
if option==1:
self.fun3()
def fun3(self):
self.t1=self.eg.gen(0)
self.t2=self.eg.gen(1)
self.worksheet_A.write(self.i,self.i,self.t1)
self.worksheet_A.write(self.i,self.i+1,self.t2)
self.i+=1
option=int(sys.argv[1])
if len(sys.argv)==2:
p=main_cls()
if option==1:
p.fun1()
else:
pass
else:
print "Wrong command"
libex.py
class exlib():
def __init__(self):
self.a="duh"
def gen(self,x):
if int(x)==0:
return(self.a)
elif int(x)==1:
self.a=str(self.a+" "+self.a+" "+self.a+" !!!")
return(self.a)
Now, this works in this particular case but in the actual code, it doesn't. The file itself is not getting created in the output directory. Then, I added the following line:
print "Workbook created at path : ",self.workbook.filename
to see if the file is getting created and it surprisingly showed with full path!!!
Where could I be going wrong here and how can I get this fixed?
UPDATE1: I played around a bit with it and found that removing self from self.workbook moving workbook to __init__(self) creates the file with the initial values populated.
UPDATE2: Have replicated my code in a minimal way as suggested. And this one works pretty well!!!
Tried to reproduce, file is being created just fine, maybe you have a problem with the self.Output_fold variable, or with file permissions or with your code editor's file explorer.
Related
First of all, I'm pretty new in multiprocessing and I'm here for learning of all of you. I have several files doing something similar to this:
SharedClass.py:
class simpleClass():
a = 0
b = ""
.....
MyProcess.py:
import multiprocessing
import SharedClass
class FirstProcess(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
def modifySharedClass():
# Here I want to modify the object shared with main.py defined in SharedClass.py
Main.py:
from MyProcess import FirstProcess
import sharedClass
if __name__ == '__main__':
pr = FirstProcess()
pr.start()
# Here I want to print the initial value of the shared class
pr.modifySharedClass()
# Here I want to print the modified value of the shared class
I want to define a shared class (in SharedClass.py), in a kind of shared memory that can be readed and writted for both files Main.py and MyProcess.py.
I have try to use the Manager of multiprocessing and multiprocessing.array but Im not having good results, the changes made in one file are not beeing reflected in the other file (maybe Im doing this in the wrong way).
Any ideas? Thank you.
I want to access the calling environment from an imported module.
import child
…
def test(xxx):
print("This is test " + str(xxx))
child.main()
…
now on child:
import inspect
def main():
caller = inspect.currentframe().f_back
caller.f_globals['test']("This is my test")
This works, but it's not fancy. Is there a simplification like 'self' when use in a class? the idea is to do: caller.test('abc') instead.
One option to pass the caller as a parameter like: child.main(self), however self is not available in this context.
Python only load one version of a module so, tempted with this idea:
import sys
myself=sys.modules[__name__]
a then sending myself to the child:
…
child.main(myself)
…
Creates a reference to (a new) module, but not the running one, this is like creating a new class: one code buy a different environment.
If you already have a way of accessing the correct functions and data that works, why not just store f_globals on an instance of a wrapper class and then call things from the instance as if they were unbound properties? You could use the class itself, but using an instance ensures that the data you get from the imported file are valid when you create the object. Then you can access using the dot operator the way you want. This is your child file:
import inspect
class ImportFile:
def __init__(self, members):
self.__dict__.update(members)
def main():
caller = inspect.currentframe().f_back
imported_file = ImportFile(caller.f_globals)
imported_file.test("This is my test")
Outputs:
This is test This is my test
Admittedly, I don't have your setup, importantly the module you're trying to pull from, so it's hard to confirm whether or not this will work for you even though it has for me, but I think you could also use your method of calling main with globals() or even inspect.getmembers() since while inside the module you're importing you're still on the frame you're accessing with f_back from inside child.
The imported module:
import child
def test(xxx):
print("This is test " + str(xxx))
child.main(globals())
Child:
import inspect
class ImportFile:
def __init__(self, members):
self.__dict__.update(members)
def main(caller):
imported_file = ImportFile(caller)
imported_file.test("This is my test")
Outputs:
This is test This is my test
It my first try to realize a "little bit bigger" project in python. Thus I want to structure the whole project using different python files. I also need some global variables. The following example works, if I put everything in one file. As soon as I split in two files it doesn't work anymore. What's an elegant way to solve the problem:
class MyClass:
def call(self):
print("In Methode call")
self.check()
def check(self):
global a
if a:
print("a ist True")
a = False
else:
print("a ist False")
a = True
def methode3(self):
print("In methode 3")
if __name__=="__main__":
a=True
instanz = MyClass()
instanz.methode3()
instanz.call()
instanz.check()
This script itself works fine.
If I call it now from the following second script, I get the error that 'a'is not defined. Call of instanz.methode3() works of course.
import test
a = True;
instanz = test.MyClass();
instanz.methode3()
instanz.call()
The following check,
if __name__=="__main__":
Is only called from when the file is run by itself as opposed to being imported. Declaring the a outside this if should work as intended.
Also, to access the new variable a, use test.a.
I would like to import all methods from a module with altered names.
For instance, instead of
from module import repetitive_methodA as methodA, \
repetitive_Class1 as Class1, \
repetitive_instance4 as instance4
I'd prefer something along the lines of
from module import * as *-without-"repetitive_"
this is a rephrasing of this clumsy unanswered question, I have not been able to find a solution or similar questions yet.
You can do it this way:
import module
import inspect
for (k,v) in inspect.getmembers(module):
if k.startswith('repetitive_'):
globals()[k.partition("_")[2]] = v
Edit in response to the comment "how is this answer intended to be used?"
Suppose module looks like this:
# module
def repetitive_A():
print ("This is repetitive_A")
def repetitive_B():
print ("This is repetitive_B")
Then after running the rename loop, this code:
A()
B()
produces this output:
This is repetitive_A
This is repetitive_B
What I would do, creating a work-around...
Including you have a file named some_file.py in the current directory, which is composed of...
# some_file.py
def rep_a():
return 1
def rep_b():
return 2
def rep_c():
return 3
When you import something, you create an object on which you call methods. These methods are the classes, variables, functions of your file.
In order to get what you want, I thought It'd be a great idea to just add a new object, containing the original functions you wanted to rename. The function redirect_function() takes an object as first parameter, and will iterate through the methods (in short, which are the functions of your file) of this object : it will, then, create another object which will contain the pointer of the function you wanted to rename at first.
tl;dr : this function will create another object which contains the original function, but the original name of the function will also remain.
See example below. :)
def redirect_function(file_import, suffixe = 'rep_'):
# Lists your functions and method of your file import.
objects = dir(file_import)
for index in range(len(objects)):
# If it begins with the suffixe, create another object that contains our original function.
if objects[index][0:len(suffixe)] == suffixe:
func = eval("file_import.{}".format(objects[index]))
setattr(file_import, objects[index][len(suffixe):], func)
if __name__ == '__main__':
import some_file
redirect_function(some_file)
print some_file.rep_a(), some_file.rep_b(), some_file.rep_c()
print some_file.a(), some_file.b(), some_file.c()
This outputs...
1 2 3
1 2 3
I am a bit new to Python, and for some reason I can't get my head around something.
From the command line I run this
python3 myfile.py
And it works, at the bottom of the file is this, which runs my class, the bit that runs the class is show below (I have just included a bit of the section that calls the rest
if __name__ == "__main__":
dir = os.getcwd()
reportoutputpath="reports"
reportfilename=casedetails['hcname'] + ".html"
......
What I want to do, is run the complete file from my code, I tried this
pathforidefiles="/home/ubuntu/idefiles"
sys.path.append(pathforidefiles)
module = __import__("clean-Fern_Britton_Testcase_01")
This seems to read the file (I have a print line right at the top and that does seem to work, but nothing actually gets executed. I am sure I am missing something fundamental about the way Python works, but I am a bit lost.
Edit
I think I could be goint about this the wrong way, and think my question could be. How do I move what is in the main section of the file to me imported into the file that is doing the importing
The file to be imported is like this
class Examplecase01(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(30)
self.base_url = "http://example.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_fern_britton_testcase01(self):
driver = self.driver
....
if __name__ == "__main__":
dir = os.getcwd()
reportoutputpath="reports"
reportfilename=casedetails['hcname'] + ".html"
outfile = open(dir + "/" + reportoutputpath + "/" + reportfilename, "w")
loader = unittest.TestLoader()
suite = unittest.TestSuite((
loader.loadTestsFromTestCase(FernBrittonTestcase01)))
runner = HTMLTestRunner(stream=outfile,
verbosity=2,
title=casedetails['hcname'],
description=casedetails['hcdescription'])
t = unittest.main(exit=False)
print (t.result)
Then in the file that is doing the importing
mymodule=importlib.import_module('cleantest')
#code as above
t = unittest.mymodule(exit=False) #to replace t = unittest.main(exit=False)
The error I get is: module 'unittest' has no attribute 'mymodule'
So what do I need to do to make my code (that was in main) to work in my view that is doing the importing?
After some thought on what I actually wanted to do, this is what I came up with (It works). I am only really interested in running this from the site, not from the command line
loadfile="my-py-file-that-was-created-and-exported-from-the-IDE"
sys.path.append("directory-of-where-my-test-case-is")
mymodule=importlib.import_module(loadfile)
print(mymodule.casedetails['hcversion']) #I can access values in a dict on the imported file
#the below then gets the test case from the imported file
suite = unittest.TestSuite((loader.loadTestsFromTestCase(mymodule.Testcase01)))
In the view that does the work, as well as the above code, I also have most of the code that was in the main section of the original test case
I have other issues\questions, but this one is solved
Thanks
Grant