1

I want to find an instance of a class, where an attribute has a certain value:

import numpy as np
import inspect
import matplotlib.pyplot as plt

class Frame():
    def __init__(self, img, idx):
        self.image = img
        self.idx = idx

for i in range(10):
    img = np.random.randint(0, high=255, size=(720, 1280, 3), dtype=np.uint8) # generate a random, noisy image
    Frame(img, i)

# Pseudo Code below:
frame = inspect.getmembers(Frame, idx=5) # find an instance of a class where the index is equal to 5
plt.imshow(frame.img)
Trenera
  • 1,435
  • 7
  • 29
  • 44
  • 2
    Why are you not saving the instances you created into a list? – FlyingTeller Mar 01 '18 at 09:30
  • 1
    You are creating and then discarding the `Frame` instances. – Ignacio Vergara Kausel Mar 01 '18 at 09:30
  • 1
    From your example it looks like you are mixing two things: defining a Frame object (which contains an image) and defining a *collection* of Frames (which contains an index of frames). So it looks like a xy problem: you probably just need to save Frame instances in a dictionary/list and then access the Frame you need – FLab Mar 01 '18 at 09:31
  • 1
    And what is wrong with your code? What do you get?... – Ma0 Mar 01 '18 at 09:31
  • The above is just an example. Yes, I can put them into a list, but that won't help me if the variable is not index, but a "string" for example. – Trenera Mar 01 '18 at 09:31
  • 1
    In that case use a dictionary – lxop Mar 01 '18 at 09:32
  • As stated in the code comments, the second to last line is a pseudo code. – Trenera Mar 01 '18 at 09:33

2 Answers2

1

From your example it looks like you are mixing two things: defining a Frame object (which contains an image) and defining a collection of Frames (which contains multiple frames, indexed so you can access them as you prefer).

So it looks like a xy problem: you probably just need to save Frame instances in a dictionary/list type of collection and then access the Frame you need.

Anyway, you can access the value of an attribute of an object using getattr.

all_frames = []

for i in range(10):
    img = np.random.randint(0, high=255, size=(720, 1280, 3), dtype=np.uint8) # generate a random, noisy image
    all_frames.append(Frame(img, i))

frames_to_plot = [frame for frame in all_frames if getattr(frame, index) == 5]

for frame in frames_to_plot:
    plt.imshow(frame.img)
FLab
  • 7,136
  • 5
  • 36
  • 69
  • I don't want to look for the instance in the loop. I want to be able to access instances outside the loop, by referring to some of their properties, whitout saving them into a list. The instances exist in the memmory, but not as a variable (like your "a_class"), but under some self generated string of randome letters and numbers – Trenera Mar 01 '18 at 09:38
  • is there any specific reason you don't want to save it to variable? – FLab Mar 01 '18 at 09:41
  • I am creating an instance for every frame in a video. Later, I am manipulating the images and change the values of some of the attributes. Finally, I need to find the frames that have some of this parameters in a specific range / have a certain value. Even if I save it to a variable, it wouldn't make any sense, as the variable names cannot reflect the information that I use to filter all frames later – Trenera Mar 01 '18 at 09:47
  • Understood. as you can access the attributes using getattr, you can save all frames to a list (or any collection) and later filter/select them based on the attributes of the instance. Does the new solution work better for you? – FLab Mar 01 '18 at 09:51
  • Thanks! Both your and Ev. Kounis answers are correct, however you introduced the list of objects, which is the exact solution I was looking for – Trenera Mar 01 '18 at 09:55
1

Assuming this class:

class Frame():
    def __init__(self, img, idx):
        self.image = img
        self.idx = idx

and two instances:

a = Frame('foo', 1)
b = Frame('bar', 2)

You can find the one with idx=1 like so:

import gc


def find_em(classType, attr, targ):
    return [obj.image for obj in gc.get_objects() if isinstance(obj, classType) and getattr(obj, attr)==targ]

print(find_em(Frame, 'idx', 1))  # -> ['foo']

Note that if you have a big code with lots of objects created in memory, gc.get_objects() will be big and thus this approach rather slow and inefficient. The gc.get_objects() idea I got from here.

Does this answer your question?

Ma0
  • 15,057
  • 4
  • 35
  • 65
  • Thanks, that answers my question. However, I now realize that my assumption that the instances are kept in the memory is wrong, so a list will be still needed if I don't save them to a variable. I selected FLab answer, as he reflected on that. – Trenera Mar 01 '18 at 09:53