Python Forum
how the class works - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: how the class works (/thread-25038.html)

Pages: 1 2


how the class works - berckut72 - Mar-16-2020

Hello!
I wrote a very small program and created a class in it for loading pictures without defining methods. I was surprised to find that the part of the code that is in the class is executed without calling the class - the "print" operator worked. I would like to know - should it be so? If this is correct, then why is this happening?

import os
import tkinter as tk
from tkinter import*
from PIL import Image, ImageTk

root = tk.Tk()

class ImageInst:
    bild_list_image     = []#список картинок здания

    '''загрузка картинок строения в bild_list'''
    path = 'C:\\ws5_class\\general\\bilds\\'
    for i, filename in enumerate(os.listdir(path)):
        if filename.find("bild") == False:
            if (filename.endswith(".png") or filename.endswith(".PNG")):
                path1 = path + '\\' + filename
                im = Image.open(path1).convert('RGBA')
                im_01 = ImageTk.PhotoImage(im)
                bild_list_image.append(im_01)
    print('bild_list_image: OK')


root.mainloop()



RE: how the class works - buran - Mar-16-2020

it's a valid code and is executed once - at class definition. you will never be able to execute that code (lines 12-20) again. Basically you don't need it to be within "class". bild_list_image is a class attribute and will be accessible.
Similar question here:
https://python-forum.io/Thread-Class-Instances-called-in-the-wrong-order


RE: how the class works - berckut72 - Mar-16-2020

If I understand correctly, then all classes are executed once during the definition, and then they must be called explicitly? So that the code inside the class does not execute when defining the class, should it be styled as a method?


RE: how the class works - buran - Mar-16-2020

If there code inside class, that is not method/property, it will be executed at class definition. That is when class attributes are initialized. At the time of class definition methods are not executed, just defined. In this case you probably want to put that code in __init__() method. Look at my example in the thread I linked.


RE: how the class works - berckut72 - Mar-16-2020

I wanted to find out that when defining a class, the method does not execute, unlike a property. Thanks!

In your example, everything is very well explained, but for me it was news)))

If you may, then another question:
why without this line "root = tk.Tk()" at the beginning of the program this line "im_01 = ImageTk.PhotoImage(im)" is not executed? I thought it was a string from pil, and it was from Tk.


RE: how the class works - buran - Mar-16-2020

(Mar-16-2020, 06:57 PM)berckut72 Wrote: why without this line "root = tk.Tk()" at the beginning of the program this line "im_01 = ImageTk.PhotoImage(im)" is not executed?
Not sure I understand that. Would you explain? Do you get error or what? There shouldn't be a problem with that line. If you print bild_list_image you should get list of PIL.ImageTk.PhotoImage objects


RE: how the class works - berckut72 - Mar-17-2020

This code works well:

import tkinter as tk
from tkinter import*
from PIL import Image, ImageTk

root = tk.Tk()

fon1    = Image.open('C:\\ws5_class\\general\\g06.PNG').convert('RGBA')
fon_im1 = ImageTk.PhotoImage(fon1)
print('fon_im1: '+str(fon_im1))#fon_im1: pyimage1
And this code does not work:
import tkinter as tk
from tkinter import*
from PIL import Image, ImageTk

#root = tk.Tk()

fon1    = Image.open('C:\\ws5_class\\general\\g06.PNG').convert('RGBA')
fon_im1 = ImageTk.PhotoImage(fon1)
print('fon_im1: '+str(fon_im1))
Error:
Error:
Traceback (most recent call last): File "wsmod02.py", line 8, in <module> fon_im1 = ImageTk.PhotoImage(fon1) File "C:\Users\беркут\AppData\Roaming\Python\Python38\site-packages\PIL\ImageTk.py", line 118, in __init__ self.__photo = tkinter.PhotoImage(**kw) File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 4061, in __init__ Image.__init__(self, 'photo', name, cnf, master, **kw) File "C:\Program Files\Python38\lib\tkinter\__init__.py", line 3994, in __init__ raise RuntimeError('Too early to create image') RuntimeError: Too early to create image Exception ignored in: <function PhotoImage.__del__ at 0x000002518C051DC0> Traceback (most recent call last): File "C:\Users\беркут\AppData\Roaming\Python\Python38\site-packages\PIL\ImageTk.py", line 124, in __del__ name = self.__photo.name AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
I thought this line "fon_im1 = ImageTk.PhotoImage(fon1)" refers to PIL, but it refers to tkinter


RE: how the class works - buran - Mar-17-2020

1. You are right - ImageTk is PIL/Pillow class
2. PIL.ImageTk is convenient wrapper around tkinter.PhotoImage class
3. Looking at the error traceback, when you try to create ImageTk instance, it try to instantiate object of tkinter.PhotoImage class and assign it to __photo attribute of PIL.ImageTk object.
4. Looking at the tkinter code,tkinter.PhotoImage in turn inherits from tkinter.Image class. tkinter.Image.__init__() method needs master attribute. That is the parent widget of the tkinter.Image. If you don't explicitly pass one, it search for default one - available tkinter.Tk() instance.
5. without root = tk.Tk() there is no Tk() instance in your program and it fails
6. That is the first error you get RuntimeError: Too early to create image which is "ignored"
7. However because there is no self.__photo - you get the next AttributeError.

I am not using tkinter, so I was not familiar with PIL.ImageTk. It was not clear in the docs that it's a wrapper. So my previous statement that there should not be a problem was not correct, i.e. I learned something new


RE: how the class works - berckut72 - Mar-17-2020

I didn’t know that either)))
To solve my problem, I saw a code example of how this problem can be solved and applied this code without really understanding it. The main thing is that it works! However, playing with the code for my own purposes, I realized that everything is not so simple and in addition to simple copying, you still need to know what it is and how it works. Your explanation is subject to this, thanks!


RE: how the class works - buran - Mar-17-2020

Maybe you can benefit from our basic OOP/class tutorials in the tutorial section if you are not familiar with OOP fundamentals