I would like to expand the class variable solution provided by Hkoof, by adding direct reference to the instancies, which can also help keeping a class-consistent instance list, allowing access to the previous/next created instance.
The only problem (which, actually, isn't covered by other solutions either) is that the removal of an instance requires an explicit method call, as del
won't suffice: __del__
is only called as soon as there's no reference left to the object. Since there's obviously no way to know if the user/programmer is keeping any reference to it, we need an explicit way to do that; it won't ensure that the instance will be garbage collected, as that will only happen as soon as there's no reference left to it.
class NoteBlock(object):
instancies = []
def __init__(self, id):
self.id = id
def __new__(cls, *args, **kwargs):
instancy = object.__new__(cls)
cls.instancies.append(instancy)
return instancy
def delete(self):
self.instancies.remove(self)
# the following property methods are only useful for "browsing" between the
# instance list
@property
def previous(self):
try:
# "-1" index returns the last object in the instancies list, we
# don't want that...
previous_index = self.instancies.index(self) - 1
assert previous_index >= 0
return self.instancies[previous_index]
except:
return
@property
def next(self):
try:
return self.instancies[self.instancies.index(self) + 1]
except:
return
# create some random objects
from random import randrange
scope_instance_list = []
print('Creating instancies:')
for i in range(8):
index = randrange(100)
block = NoteBlock(index)
scope_instance_list.append(block)
print('\t{} - Block {} created'.format(i + 1, index))
# remove a single instance
toRemoveIndex = randrange(8)
toRemove = scope_instance_list.pop(toRemoveIndex)
print('\nRemoving instance n. {} ({})...'.format(toRemoveIndex + 1, format(toRemove.id)))
# we can't use "del", as the __del__ magic method only works as soon as there is
# *no* reference left for the object: since we're keeping the "instancies" list
# it will never be called, then we need to use an "internal" way to do that;
# keep in mind that if you have *any* reference to that object, it will never be
# garbage collected until it's "released".
toRemove.delete()
print('Done!\n')
# show the current instance list, including previous and next instancies,
# according to the existing objects
print('Remaining instance list (class instance based):')
for i, inst in enumerate(block.instancies):
print('\t{} - Block {}: previous: {}, next: {}'.format(
i + 1,
inst.id,
inst.previous.id if inst.previous else None,
inst.next.id if inst.next else None))
Example output:
Creating instancies:
1 - Block 10 created
2 - Block 23 created
3 - Block 4 created
4 - Block 28 created
5 - Block 9 created
6 - Block 67 created
7 - Block 70 created
8 - Block 73 created
Removing instance n. 5 (9)...
Done!
Remaining instance list (class instance based):
1 - Block 10: previous: None, next: 23
2 - Block 23: previous: 10, next: 4
3 - Block 4: previous: 23, next: 28
4 - Block 28: previous: 4, next: 67
5 - Block 67: previous: 28, next: 70
6 - Block 70: previous: 67, next: 73
7 - Block 73: previous: 70, next: None