I have a Python program where a function imports another script and runs it. But the script gets run only the first time the function is called.
def Open_Generator(event):
import PasswordGenerator
Any tips?
*The function is called using a button in a tkinter window
This is by design. You should only import a module once. Trying to import a module more than once will cause Python to re-fetch the module object from the cache, but this won't cause the module's code to execute a second time.
Most well-designed modules won't do anything right away when you import them, or at least won't do anything obviously visible. Generally, if you want a module to do work, you need to call one of its functions.
I'm guessing your PasswordGenerator module has some code at the file-level scope. In other words, it has code that isn't inside a function. Try to move that code into a function. Then you can call that function from Open_Generator.
import PasswordGenerator
def Open_Generator(event):
my_password = PasswordGenerator.generate_password()
Related
I'm new to python and doing an assignment. It's meant to be done with linux but as I'm doing it by myself on my own computer I'm doing it on windows.
I've been trying to do this test system that we use looking like this:
>>> import file
>>> file.function(x)
"Answer that we want"
Then we run it through the linux terminal. I've been trying to create my own way of doing this by making a test file which imports the file and runs the function. But then on the other hand of just running the function it runs the whole script. Even though it's never been called to do that.
Import file
file.function(x)
That's pretty much what I've been doing but it runs the whole "file". I've also tried from file import function; it does the same.
What kind of script can I use to script the "answer that I want" for the testfile? As when we run in through linux terminal it says if it has failed or scored.
importing a file is equivalent to running it.
When you import a file (module), a new module object is created, and upon executing the module, every new identifier is put into the object as an attribute.
So if you don't want the module to do anything upon importing, rewrite it so it only has assignments and function definitions.
If you want it to run something only when invoked directly, you can do
A = whatever
def b():
...
if __name__ == '__main__'
# write code to be executed only on direct execution, but not on import
# This is because direct execution assigns `'__main__'` to `__name__` while import of any way assigns the name under which it is imported.
This holds no matter if you do import module or from module import function, as these do the same. Only the final assignment is different:
import module does:
Check sys.modules, and if the module name isn't contained there, import it.
Assign the identifier module to the module object.
from module import function does
Check sys.modules, and if the module name isn't contained there, import it. (Same step as above).
Assign the identifier function to the module object's attribute function.
You can check if the module is imported or executed with the __name__ attribute. If the script is executed the attribute is '__main__'.
It is also good style to define a main function that contains the code that should be executed.
def main()
# do something
pass
if __name__ == '__main__'
main()
I want to execute a function once a module is imported. I know I can just call the function directly at the end of the module to achieve this.
For eg..
# Inside File Test.py
import something
from test import sayhi
# Lots of functions and classes are defined here
# End of the module
sayhi()
But, Since there will be several people changing the file continuously, I do not want to put sayhi() at the end of the file but want sayhi() to be called once the loading finishes. is there a hook in python that executes once the import module statement finishes? I am looking for something like sys.settrace with the difference being it should be called only after the import finishes.
So I've been doing a lot of research and couldn't find a proper answer. I'm quite new to python so sorry if this is a simple question.
So, basically, I'm creating an UI that has a button that should call a function from another .py file. What I did so far is append the file's folder to sys.path and import the .py file as something else. Example, let's say I'm importing myTools.py:
import myTools as mt
Now I can successfully access all functions within myTools via mt.mainFunction() or anything with the mt. prefix.
Now my question:
When I run mt.myFunction() directly it works just fine. Problem is that mainFunction() is another UI that calls different functions at different times. All these functions are on the myTools file.. but Maya won't find them because when they are called within the mainFunction() they don't have the mt prefix.
I mean, I could run those defs on the userSetup.py but it's quite a big code and I wanted to do that the cleanest way :)
Any ideas?
Thanks in advance!
EDIT:
So I just realized is only one function that isn't working. I'm getting this error:
# Error: NameError: file <maya console> line 1: name 'annotationToLocator' is not defined #
Because of that error, I thought that my mainfunction couldn't find any other function on the module.
The actual code where I declare this function:
jobNum = cmds.scriptJob(e=['SelectionChanged', 'annotationToLocator()'])
def annotationToLocator ():
selList = cmds.ls(sl=True)
for item in selList:
if '_ANN' in str(item):
cmds.select(item,d=True)
newItem = str(item).replace('_ANN', '_LOC')
cmds.select(newItem,add=True)
A couple of weird things about this:
1) It works perfectly when I run the code directly.
2) I'm importing the module on the userSetup file.. I'm getting the error above not only when I try to actually run the function that calls this one, but also when Maya starts..
I tried commenting the scriptjob line and now it works just fine, although obviously now I don't have the scriptjob running. I think is some issue with modules and scriptjobs?!
I'm sorry, I know I got off of the original question path here! :)
This sounds like typical python behaviour and should work correctly. Each module has it's own global scope and each function defined in that module will have access to everything defined in that scope.
So in the myTools module each function has access to each other by name, and every function defined in your main module will have access to the mt module object and can get the functions as it's attributes.
You problem stems from using string references to your function. While that works, it only works if they function you're calling by string is in the global python scope -- which usually means it only works in the listener.
The better way to do any maya callbacks is by passing the functions directly to the callback as function objects, not as strings:
import mymodule
cmds.scriptJob(e=('somethingSelected', mymodule.fancyfunction))
Note that mymodule.fancyfunction is passed without parens: you are telling Maya "use this function." If you did it as mymodule.fancyfunction() you'd be telling Maya to use the result of a call to the function , not the function itself.
I'm new to python and doing an assignment. It's meant to be done with linux but as I'm doing it by myself on my own computer I'm doing it on windows.
I've been trying to do this test system that we use looking like this:
>>> import file
>>> file.function(x)
"Answer that we want"
Then we run it through the linux terminal. I've been trying to create my own way of doing this by making a test file which imports the file and runs the function. But then on the other hand of just running the function it runs the whole script. Even though it's never been called to do that.
Import file
file.function(x)
That's pretty much what I've been doing but it runs the whole "file". I've also tried from file import function; it does the same.
What kind of script can I use to script the "answer that I want" for the testfile? As when we run in through linux terminal it says if it has failed or scored.
importing a file is equivalent to running it.
When you import a file (module), a new module object is created, and upon executing the module, every new identifier is put into the object as an attribute.
So if you don't want the module to do anything upon importing, rewrite it so it only has assignments and function definitions.
If you want it to run something only when invoked directly, you can do
A = whatever
def b():
...
if __name__ == '__main__'
# write code to be executed only on direct execution, but not on import
# This is because direct execution assigns `'__main__'` to `__name__` while import of any way assigns the name under which it is imported.
This holds no matter if you do import module or from module import function, as these do the same. Only the final assignment is different:
import module does:
Check sys.modules, and if the module name isn't contained there, import it.
Assign the identifier module to the module object.
from module import function does
Check sys.modules, and if the module name isn't contained there, import it. (Same step as above).
Assign the identifier function to the module object's attribute function.
You can check if the module is imported or executed with the __name__ attribute. If the script is executed the attribute is '__main__'.
It is also good style to define a main function that contains the code that should be executed.
def main()
# do something
pass
if __name__ == '__main__'
main()
Python won't allow me to import classes into eachother. I know there is no "package" solution in Python, so I'm not sure how this could be done. Take a look at my files' codes:
file Main.py:
from Tile import tile
tile.assign()
class main:
x = 0
#staticmethod
def assign():
tile.x = 20
file Tile.py:
from Main import main
main.assign()
class tile:
x = 0
#staticmethod
def assign():
main.x = 20
I get the error "class tile can not be imported".
If file A imports file B, and file B imports file A, they would keep importing each other indefinitely until the program crashed.
You need to rethink your logic in a way that doesn't require this circular dependency. For example, a 3rd file could import both files and perform both assignments.
You have your import backwards and the from needs to have the name of the module
from Tile import tile
Python begins executing Main.py. It sees the import, and so goes to execute Tile.py. Note that it has not yet executed the class statement!
So Python begins executing Tile.py. It sees an import from Main, and it already has that module in memory, so it doesn't re-execute the code in Main.py (even worse things would go wrong if it did). It tries to pull out a variable main from the Main module, but the class statement binding main hasn't executed yet (we're still in the process of executing the import statement, advice that line). So you get the error about there not being a clsss main in module Main (or Tile, if you started from there).
You could avoid that by importing the modules rather than importing classes out of the modules, and using qualified names, but then you'd fall one line down when Main.main doesn't work. Your code makes no sense I'm a dynamic language; you can't have both the definition of class main wait until after tile.assign has been called and the definition of class tile wait until after main.assign has been called.
If you really need this circular dependency (it's often, but not always a sign that something has gone wrong at the design stage), then you need to separate out "scaffolding" like defining classes and functions and variables from "execution", where you actually call classes and functions or use variables. Then your circular imports of the "scaffolding" will work even though none of the modules will be properly initialized while the importing is going on, and by the time you get to starting the "execution" everything will work.