Missing module attribute showing up for a linked Python script - python-3.x

In my learning to use Python one of the things I am trying to do is to separate like functions/details in to different scripts. In a previous script that I wrote that was a batch file renamer, I have created a GUI and I wanted to separate the GUI and its specific functions into a dedicated script that the parent script can call upon at initial opening.
The parent script is called TVShowRenamerv2.py
The GUI script is called GUI.py
From the parent script, this is imported
import tkinter as tk
from tkinter import simpledialog, filedialog, messagebox, ttk
import GUI as g
And then called on a line near the end of the script
rg = g.Renamer_GUI()
I am using VS Code as my IDE, and I get no errors prior to running the script. Once I do run the script, I get the following error:
File "TVShowRenamerv2.py", line 4, in <module>
import GUI as g
File "D:\Projects\Python\TVShowRenamer\v2\GUI.py", line 3, in <module>
import TVShowRenamerv2 as t2
File "D:\Projects\Python\TVShowRenamer\v2\TVShowRenamerv2.py", line 172, in <module>
rg = g.Renamer_GUI()
AttributeError: module 'GUI' has no attribute 'Renamer_GUI'
This is from the GUI.py
from tkinter import ttk
import TVShowRenamerv2 as t2
class Renamer_GUI():
VS Code seems to tie the two together properly because I don't get any errors when I call functions from the two scripts, so I am not sure what the issue is. Any help is greatly appreciated. Thank you.

As it turns out, I was implementing a circular import of the two different scripts (ie, both scripts were importing each other). As a more experienced Python dev friend pointed out to me, this is bad.
We initially solved the problem by placing the items that the debugger was stating as missed attributes in one of the scripts inside a name == main if statement, but that was a short term fix that ultimately ended up creating additional issues.
So I ended up creating a third script (A controller, a GUI, and now a manipulable values). The controller would create the TK window and instantiate the GUI class inside it, and then the GUI could manipulate the values in the third script. This seemed to be the better long term solution.
Thank you very much for the assistance!

Related

NameError: name 'log10' is not defined in function called in script

Why log10() is failing to be recognized when called within a function definition in another script? I'm running Python3 in Anaconda (Jupyter and Spyder).
I've had success with log10() in Jupyter (oddly without even calling "import math"). I've had success with defining functions in a .py file and calling those functions within a separate script. I should be able to perform a simple log10.
I created a new function (in Spyder) and saved it in a file "test_log10.py":
def test_log10(input):
import math
return math.log10(input)
In a separate script (Jupyter notebook) I run :
import test_log10
test_log10.test_log10(10)
I get the following error:
"NameError: name 'log10' is not defined"
What am I missing?
Since I'm not using the environment of Jupyther and alike, I don't know how to correct it in these system, perhaps there is some configuration file over there,check the documentation.
But exactly on the issue, when this happens its because python has not "linked" well something at the import, so I suggest a workaround with the libs in the next way:
import numpy as np
import math
and when you are using functions from math, simply add the np. before, i.e.:
return math.log10(input)
to
return np.math.log10(input)
Exactly I don't know why the mismatch, but this worked for me.

I want to embed python console in my tkinter window.. How can i do it?

I am making a text editor and want to add a feature of IDLE in my app. So i want an frame with python IDLE embedded in it with all menus and features which original python IDLE gives.
I looked in source of idle lib but cannot find a solution.
try:
import idlelib.pyshell
except ImportError:
# IDLE is not installed, but maybe pyshell is on sys.path:
from . import pyshell
import os
idledir = os.path.dirname(os.path.abspath(pyshell.__file__))
if idledir != os.getcwd():
# We're not in the IDLE directory, help the subprocess find run.py
pypath = os.environ.get('PYTHONPATH', '')
if pypath:
os.environ['PYTHONPATH'] = pypath + ':' + idledir
else:
os.environ['PYTHONPATH'] = idledir
pyshell.main()
else:
idlelib.pyshell.main()
This code is of pyshell.pyw found under idlelib folder in all python install
I searched the idle.pyw and found that it uses a program pyshell which is real shell. So how can i embed it.
I want a Tkinter frame with python IDLE shell embedded in it.Please give the code. Thanks in advance.
idlelib implements IDLE. While you are free to use it otherwise, it is private in the sense that code and interfaces can change in any release without the usual back-compatibility constraints. Import and use idlelib modules at your own rish.
Currently, a Shell window is a Toplevel with a Menu and a Frame. The latter has a Text and vertical Scrollbar. It is not possible to visually embed a Toplevel within a frame (or within another Toplevel or root = Tk()). top = Toplevel(myframe) works, but top cannot be placed, packed, or gridded within myframe.
I hope in the future to refactor editor.py and pyshell.py so as to separate the window with menu from the frame with scrollable text. The result should include embeddable EditorFrame and ShellFrame classes that have parent as an arguments. But that is in the future.
Currently, one can run IDLE from within python with import idlelib.idle. However, because this runs mainloop() (on its own root), it blocks and does not finish until all IDLE windows are closed. This may not be what one wants.
If having Shell run in a separate window is acceptable, one could extract from python.main the 10-20 lines needed to just run Shell. Some experimentation would be needed. If the main app uses tkinter, this function should take the app's root as an argument and not call mainloop().
Tcl having Tkcon.tcl . when each thread source (means run/exec) the Tkcon.tcl
each thread will pop up a Tk shell/Tk console/tkcon.tcl very good idea for debug. and print message individually by thread.
Python having idle.py ... and how to use it ? still finding out the example .
The are same Tk base . why can't find an suitable example? so far ... keep finding...

Avoiding multiple import in Kivy when calling a function from a different file

I'm developing a small app using kivy and python3.6 (I'm still a beginner). I'm planning to separate the code in different files for clarity, however I have encountered a problem in a specific situation. I have made minimal working example to illustrate.
I have the following files:
main.py
main.kv
module.py
module.kv
Here a minimal code:
main.py:
from kivy.app import App
from kivy.uix.button import Button
from kivy.lang import Builder
import module
Builder.load_file('module.kv')
class MainApp(App):
pass
def function():
print('parent function')
if __name__ == '__main__':
MainApp().run()
main.kv:
CallFunction
module.py:
from kivy.uix.button import Button
class CallFunction(Button):
def call_function(self):
from main import function
function()
module.kv:
<CallFunction>:
id : parent_button
text: 'Call parent button'
on_press: self.call_function()
So the problem is that when I run this code, I receive a warning
The file /home/kivy/python_exp/test/module.kv is loaded multiples times, you might have unwanted behaviors.
What works:
If the function I want to call is part of the main app class, there is no problem
If the function is part of the module.py there is no problem
If the function is part of another module, there is no problem
What doesn't work
I cannot call a function which is in the main.py. If I use the import the function as the beginning of module.py, kivy has a weird behavior and call everything twice. Calling within this call_function allows to have a proper interface, but I get the warning that the file has been loaded multiple time.
There are easy workarounds, I'm well aware of that, so it's more about curiosity and understanding better how the imports in kivy works. Is there a way to make it work?
I wanted to use the main.py to initialize different things at the startup of the app. In particular I wanted to create an instance of another class (not a kivy class) in the main.py and when clicking on the button on the interface, calling a method on this instance.
Thanks :)
When you import something from another python module the python virtual machine execute this module. In the call_function you import function from the main file so everytime you press the CallFunction the module.kv is loaded.
To solve this it is recommended to include the other kv files in your main kv file.
You can also move the import statement from the method to the top of the module file.
Your kv file is loaded twice because the code is executed twice. This is due to how pythons module system works and kivy just realized that loading the kv twice is probably not what you want.
Generally python objects live in a namespace. So when a function in the module foo looks up a variable the variable is searched in the namespace of the module. That way if you define two variables foo.var and bar.var (in the modules foo and bar resp.) they don't clash and get confused for each other.
The tricky thing is that the python file you execute is special: It does not create a module namespace but the __main__ namespace. Thus if you import the file you are executing as __main__ it will create a whole new namespace with new objects and execute the module code. If you import a module that was already imported in the current session the module code is not executed again, but the namespace already created is made available. You don't even need two files for that, put the following in test.py:
print("hello!")
print(__name__)
import test
If you now execute python test.py you will see two hello! and once __main__ and once test.
You can find more information on namespaces and how variable lookups works in python in the documentation.
Also if your function actually does some work and mutates an object that lives in main.py you might want to rethink the information flow. Often it is a good idea to bind the state and functions working on them together in classes and passing the objects then where they are called i.e. to CallFunction in your example.

seeing source code of objects in a python module

I came up with this question when I was trying to use pygame. I wrote the following line
pygame.time.
but pyCharm didn't give me a list of methods to choose. I wanted to use pygame.time.Clock() but when this happened I tried to see the source code of time but I couldn't. I was just able to see the source code of pygame module and in that, there was just the following line on 'time':
try:
import pygame.time
except (ImportError, IOError):
time = MissingModule("time", geterror(), 1)
So my question is that, what is 'time' object and where is it? is it just a compiled python file that came with pygame when I installed it? Can I see the methods inside it or is there a way to let pyCharm suggest the methods inside of it?
So my question is that, what is 'time' object and where is it?
time is not an object it is a module.
Pygame is well documented. A complete documentation of the pygame.time module can be found at pygame.time.
It is not necessary to import the module. Via pygame.time you can access all objects of the module. However, you can import all objects form the module with:
from pygame.time import *

python 3 tkinter Pycharm - error on messagebox

Im writing a GUI and I say:
from tkinter import *
Further in the program theres a function wich is:
def nameFunc():
messagebox.showinfo(........)
The problem is that by running the code in the latest Pycharm, it tells me that messagebox is not defined even if I already imported everything from tkinter, it only works if I explicitly say:
from tkinter import messagebox
This only occurs when I run the code on Pycharm, in the standard python IDLE its fine.
Why?
PyCharm is behaving exactly as it should, if you take a look at the documentation on packages:
what happens when the user writes from sound.effects import *? Ideally, one would hope that this somehow goes out to the filesystem, finds which submodules are present in the package, and imports them all. This could take a long time and importing sub-modules might have unwanted side-effects that should only happen when the sub-module is explicitly imported.
The only solution is for the package author to provide an explicit index of the package. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered.
tkinter does not define a __all__ to automatically import submodules and you should be glad it doesn't import them all automatically:
import tkinter.__main__
print("this will only print after you close the test window")
the program only continues to run after a window pops up with the current tcl/Tk version and some other content is closed, to import submodules of the package you must explicitly import them with:
from tkinter import messagebox
however as I describe in my other answer here, because of how IDLE is built it has already loaded some of the submodules when your code is being executed in the idle Shell.

Resources