Python Forum
NameError when calling a class method - 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: NameError when calling a class method (/thread-29892.html)



NameError when calling a class method - mfreudenberg - Sep-24-2020

Hi,

I'm currently starting to learn python (have already programming experience with c#).

For my first project i wanted to write a script, that sorts my camera images. The idea is to create a task list, that contains a list of image file paths, that either have or don't have exif tags.

For the first part, i have written a class, that creates a csv file with the file path and a boolean flag (has exif or not). Somehow i'm not able to successfully execute my method called 'create_tasklist'. I'm getting an error, that another method 'get_filtered_images' in that class cannot be found.

From my point of view it looks good, but still i'm getting this error. Can you take a look at the following class?:

from os import listdir, path, rename
import csv
import exifread
import datetime
from Settings import Settings

class TaskGenerator:

    def __init__(self, settings: Settings):
        self.settings = settings

    def get_task_line(self, img, image):
        tags = exifread.process_file(img)
        if tags:
            line = image + ";True"
        else:
            line = image + ";False"
        return line


    def import_exif_images(self, taskfile_relpath):
        isExif = "True"
        return import_taskfile(taskfile_relpath, isExif)


    def import_nonexif_images(self, taskfile_relpath):
        isExif = "False"
        return import_taskfile(taskfile_relpath, isExif)


    def import_taskfile(self, taskfile_relpath, isExifValue):
        current_base_path = path.dirname(path.abspath(__file__))
        taskfile_abspath = path.join(current_base_path, taskfile_relpath)

        images = []
        with open(taskfile_abspath, "r") as tasklist:
            csv_reader = csv.reader(tasklist, delimiter=';')
            # skip header line
            next(csv_reader)
            for line in csv_reader:
                if not line or len(line) < 2:
                    continue #  skip line if empty

                image_path = line[0]
                isExif = str(line[1].strip('\''))
                if isExif == isExifValue:
                    images.append(image_path.strip())

        return images

    def get_filtered_images(self):
        files = listdir(self.settings.base_path)
        images = []
        for file in files:
            abspath = path.join(self.settings.base_path, file)
            extension_array = path.splitext(abspath)
            
            extension = ""
            if extension_array and len(extension_array) > 0:
                extension = extension_array[1]
            
            if extension != "" and extension in self.settings.image_types:
                images.append(abspath)
        return images

    def create_tasklist(self, tasklist_filename):
        images = get_filtered_images(self)
        numberOfImages = len(images)

        taskfile_content = ["file;hasexif"]
        for image in images:
            with open(image, "rb") as img:
                imageIndex = images.index(image, 0, numberOfImages)
                print("processing image " + str(imageIndex) + "/" + str(numberOfImages) + "(" + image + ")")
                
                line = get_task_line(self, img, image)
                
                taskfile_content.append(line)

        current_base_path = path.dirname(path.abspath(__file__))
        taskfile_abspath = path.join(current_base_path, tasklist_filename)

        with open(taskfile_abspath, "w") as taskfile:
            print("writing task file: " + taskfile_abspath)
            taskfile_content = "\n".join(taskfile_content)
            taskfile.write(taskfile_content)
This is how i instantiate the class, and call the method:

from TaskGenerator import TaskGenerator
from Settings import Settings

base_path = r"C:\path\to\my\pictures"
copy_only = False
datetime_format_string = "%Y-%m-%d_%H-%M-%S"
exif_tag_name = "EXIF DateTimeOriginal"
image_types = [".jpg", ".png", ".JPG", ".PNG"]
settings = Settings(base_path, copy_only, datetime_format_string, exif_tag_name, image_types)

taskGenerator = TaskGenerator(settings)
taskGenerator.create_tasklist("task-list.csv")
Thats the error I'm getting:

Error:
Exception has occurred: NameError name 'get_filtered_images' is not defined File "D:\python-stuff\exifreader\TaskGenerator.py", line 67, in create_tasklist images = get_filtered_images(self) File "D:\python-stuff\exifreader\do-work.py", line 14, in <module> taskGenerator.create_tasklist("task-list.csv")
I'm not sure if i made an indentation error, therefore i posted the whole class. Otherwise I'd posted an simplified example.

Do you have an idea, what could be wrong?

Thanks in advance,

Michael


RE: NameError when calling a class method - bowlofred - Sep-24-2020

The method is in the class hierarchy, so you have to call it that way, and you can use self to do so:

# not 
images = get_filtered_images(self)

# but instead
images = self.get_filtered_images()



RE: NameError when calling a class method - mfreudenberg - Sep-25-2020

Oh boy, i would never think of that. I haven't seen this in any tutorials. Well thanks a lot!