Depends on what and how you are adding to scene.
For NPCs I’d use a spawn script that either counts the amount of identically named objects in the scene and appends a property with that number to the object.
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
listidentical = [obj for obj in scene.objects if obj.name == "objname"]
newobj = scene.addObject("objname", cont.owner, 0)
newobj["id"] = len(listidentical)
For particles maybe rather store a number of spawned particles in emitter than gameobject references to them. Particles often have a lifetime and are removed sooner or later which makes the reference cause an error.
Remember that when you spawn IDENTICAL objects, it doesn’t make actually sense to be able to differentiate between them in this arbitrary way. I recommend you to question why do you need to able to ID between them. An example:
For 3 of my NPC characters used in a cutscene I actually just cloned one character I had available at this phase until I get the other 2 done. But then I wanted to give them separate waypoints, dialogue etc so of course I had to differentiate between them. I was first annoyed at how troublesome it was but then I realized it was all because of my shortcut I was taking. I wanted some instances of the exact copies to behave differently and that is actually bad design.
Often you can go around this problem by altering the objects in some meaningful way. Maybe even visual so the player can expect them to behave differently. For example if some cubes can be pushed and others not, you better also set a different object.color after adding them for example. You can then check for object.color later in the code for if the object is pushable.