The setting get_cached_object_id in the PYXLL section of the pyxll.cfg file can be used to override how object ids for cached objects are created. This can be set to the full name (including the module name) of your own function to allow you to determine how object ids should be created.
Object ids must be unique as PyXLL will use them to look up objects from its cache. If the returned ids are not unique then the wrong objects will be found in the cache and your spreadsheets will behave in unexpected ways.
For example, you could create a new file "my_custom_object_cache_ids.py" with a function "get_cached_object_id" as follows:
# my_custom_object_cache_ids.py
def get_cached_object_id(obj):
return f"{obj.__class__.__name__} @ {id(obj)}"
Then in your pyxll.cfg file configure PyXLL to use this function as follows:
[PYXLL]
get_cached_object_id = my_custom_object_cache_ids.get_cached_object_id
Note: In the function above, "id(obj)" has been included in the string returned to ensure that the object id we are generating is unique.
Now, when you return an object from an @xl_func Python function this new get_cached_object_id function will be called with that object to get the id, and that id will be shown in Excel. When that id is passed from Excel to another function, PyXLL will find that object from its object cache and pass it to the Python function.
There can only be one function for "get_cached_object_id", and so you will have to code this one function to handle all object types. You can use the Python function isinstance to test if an object is of a specfic type if you wish to taylor how the id is generated for a specific type.
You can read more about how cached objects work in PyXLL here:
https://www.pyxll.com/docs/userguide/udfs/argtypes.html#using-python-objects-directly
Note: You can name your function however you like, as long as you configure the get_cached_object_id setting to reference your function using the name you have chosen.
Naming Python Objects
Rather than using the class name in the object id, you could use some other attribute of the object to make the id more understandable to the users of your function.
If you want to allow the user of your function(s) to pass a string to be used as part of the object id, you would name the object you create and then retrieve it in your get_cached_object_id function. For example:
class NamedObject:
def __init__(self, name):
self.name = name
class CustomObject(NamedObject):
def __init__(self, name, *args):
super().__init__(name)
# ...
# Configured in pyxll.cfg
def get_cached_object_id(obj):
obj_id = id(obj) # to ensure the id returned is unique
if isinstance(obj, NamedObject):
return f"{obj.name}@{obj_id}"
return f"{obj.__class__.__name__}@{obj_id}"
@xl_func("str name: object")
def create_object(name):
return CustomObject(name)
In your pyxll.cfg, configure this function to be used as follows (assuming the code above was saved to a Python module named "my_custom_object_cache_ids.py"):
[PYXLL]
get_cached_object_id = my_custom_object_cache_ids.get_cached_object_id