Widgets are not unique when stored in a dict in sub-class
See original GitHub issueThis may be a python feature rather than an ipywidgets bug, but thought it was worth pointing out in case someone else has a similar issue and can’t figure it out.
I am subclassing HBox
and VBox
to create self-contained “combo-widgets”. However, I noticed that when I made independent instances of my combo-widgets, the widgets they contained seemed to be connected. It turns out that because I was storing the widgets in a dict
the widgets were pointing to the same address.
Here is an MCVE:
import ipywidgets as widgets
class myBox(widgets.HBox):
def __init__(self):
self.widgets['innerbox']=widgets.Text()
super().__init__(children=[self.widgets['innerbox']])
b1 = myBox()
print(id(b1.widgets['innerbox']))
b2 = myBox()
print(id(b1.widgets['innerbox']), id(b2.widgets['innerbox']))
Result is
140583624309712
140583623982352 140583623982352
It doesn’t happen if I store the inner widget like so
self.innerbox=widgets.Text()
if I give the inner widgets different arguments every time they are instantiated they still end up pointing to the same place
import ipywidgets as widgets
import uuid
class myBox(widgets.HBox):
def __init__(self):
self.id = str(uuid.uuid1())
self.widgets['innerbox']=widgets.Text(description=str(self.id))
super().__init__(children=[self.widgets['innerbox']])
b1 = myBox()
print(b1.id, b1.widgets['innerbox'])
b2 = myBox()
print(b2.id, b2.widgets['innerbox'])
print(b1.id, b1.widgets['innerbox'])
print(id(b1.widgets['innerbox']), id(b2.widgets['innerbox']))
dfa1e66c-d865-11ea-bd85-fa163e8ac59c Text(value='', description='dfa1e66c-d865-11ea-bd85-fa163e8ac59c')
dfa587f4-d865-11ea-a034-fa163e8ac59c Text(value='', description='dfa587f4-d865-11ea-a034-fa163e8ac59c')
dfa1e66c-d865-11ea-bd85-fa163e8ac59c Text(value='', description='dfa587f4-d865-11ea-a034-fa163e8ac59c')
140583624267536 140583624267536
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (4 by maintainers)
Top Results From Across the Web
Store Widgets in Dictionary - python - Stack Overflow
Can widget objects not be stored in dictionaries? Is there a way for me to ID widgets that would allow me to store...
Read more >OrderedDict in Python - GeeksforGeeks
In Python 2.7 Ordered Dict is not dict subclass, it's a specialized container from collections module. Starting from Python 3.7, insertion order ...
Read more >Widgets - Django documentation
A widget is Django's representation of an HTML input element. The widget handles the rendering of the HTML, and the extraction of data...
Read more >15 things you should know about Dictionaries in Python
1. What is a Python dictionary? A dictionary is an unordered and mutable Python container that stores mappings of unique keys to values....
Read more >tkinter.ttk — Tk themed widgets — Python 3.11.1 documentation
Each item is identified by a unique name. The widget will generate item IDs if they are not supplied by the caller. There...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
And I think the issue was coming up in this case because
widgets
is a class variable that is defined all the way back in theWidget
base classhttps://github.com/jupyter-widgets/ipywidgets/blob/6be18d9b75353f7b4a1c328c6ea06d8959f978f6/ipywidgets/widgets/widget.py#L266-L267
So the solution is either to redefine it for the instance as I did, or use a different variable name.
I think this is an issue of class instance variables vs class variables. I just read https://stackoverflow.com/questions/45284838/are-the-attributes-in-a-python-class-shared-or-not which I found to be helpful for understanding this.
I think this issue is in how you are (or are not) initializing self.widgets. If I change your example to this:
then I get the result I think you are expecting.