Python Forum

Full Version: NameError when calling a class method
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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
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()
Oh boy, i would never think of that. I haven't seen this in any tutorials. Well thanks a lot!