Reputation: 298532
I've been cleaning up some code from a module I'm extending and I can't seem to find a way to Pythonify this code:
global_next_id = 1
class Obj:
def __init__(self):
global global_next_id
self.id = global_next_id
global_next_id += 1
This code uses a global id to keep track of instances of a class (I need the variable self.id
internally as well, and it needs to be a number).
Can anyone suggest a way to Pythonify this code?
Upvotes: 44
Views: 76431
Reputation: 1
This could work as well if you want to count the number of instances in each class of specific variables. You can import pandas and read the data into the object.
object.variableName.value_counts()
This code will output the count of instances of each class within the specified variableName
Upvotes: -1
Reputation: 1
This Will do the job
class YourClass:
counter = 0
def __init__(self):
YourClass.counter += 1
def PrintData(self):
print(self.counter)
Upvotes: -1
Reputation: 48028
You could consider using a class attribute to provide a counter. Each instance needs only to ask for the next value. They each get something unique. Eg:
from itertools import count
class Obj(object):
_ids = count(0)
def __init__(self):
self.id = next(self._ids)
Upvotes: 85
Reputation: 19
You can use dir()
function, which returns all properties and functions in the current script, to count the numbers of instances of a certain class.
len([i for i in dir() if isinstance(eval(i), ClassName)])
Upvotes: 1
Reputation: 1
class InstanceCounter(object):
# the instance counter
counter = 0
def __init__(self, val):
self.val = all
# incrementing every time an instance is created
InstanceCounter.counter += 1
def set_val(self, val):
self.val = val
def get_val(self, val):
return self.val
# accessing the instance counter should be done through a class method
@classmethod
def get_counter(cls):
return cls.counter
# See the instance counter as it increments as new instances are created
a=InstanceCounter(5)
print(a.get_counter())
b=InstanceCounter(7)
print(a.get_counter(), b.get_counter())
c=InstanceCounter(9)
print(a.get_counter(), b.get_counter(), c.get_counter())
Upvotes: 0
Reputation: 77
I found the following solution:
class Obj:
counter = 0
def __init__(self):
type(self).counter += 1
def __del__(self):
type(self).counter -= 1
It's better to use type(self).counter
instead of Obj.counter
Upvotes: 7
Reputation: 9806
This should do the job:
class Obj:
_counter = 0
def __init__(self):
Obj._counter += 1
self.id = Obj._counter
Upvotes: 31
Reputation: 963
Here is a way to count instances without descendant classes sharing the same id/count. A metaclass is used to create a separate id counter for each class.
Uses Python 3 syntax for Metaclasses.
import itertools
class InstanceCounterMeta(type):
""" Metaclass to make instance counter not share count with descendants
"""
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
cls._ids = itertools.count(1)
class InstanceCounter(object, metaclass=InstanceCounterMeta):
""" Mixin to add automatic ID generation
"""
def __init__(self):
self.id = next(self.__class__._ids)
Upvotes: 8
Reputation: 64022
Generator?
def get_next_id():
curr_id = 1
while True:
yield curr_id
curr_id += 1
Upvotes: 1