[x3d-public] x3d.py problem
vmarchetti at kshell.com
vmarchetti at kshell.com
Tue May 12 18:46:31 PDT 2020
For more background, see the short article on "mutable and immutable objects in Python" https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/ <https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/>
and follow the rule: only use immutable values as default value for function and method arguments (in Python None is immutable, and it's a singleton, there is only one None)
> On May 12, 2020, at 9:25 PM, vmarchetti at kshell.com wrote:
>
> This is an unfortunate and common bug that occurs in Python.
>
> In the definition of the class Scene (around line 8795 of x3d.py) is this definition of the __init__ function for Scene:
>
> def __init__(self, children=list()):
> self.children = children
>
> This code is read once when the x3d.py module is loaded, and it creates a class-level default value for the children argument.
> If you ever use the default value by calling Scene() {with no parameter}, this class-level instance of list is modified, and this SAME INSTANCE of list
> if used for any further calls of Scene()
>
> The way to avoid this is to define the __init__ function this way:
>
> def __init__(self, children=None):
> if children is None:
> self.children = list() # creates a new empty list for each Scene instance
> else:
> self.children = children
>
>
> Vince Marchetti
>
>
>> On May 12, 2020, at 5:59 PM, Andreas Plesch <andreasplesch at gmail.com <mailto:andreasplesch at gmail.com>> wrote:
>>
>> I discovered a simple workaround. Always pass a children parameter, even if empty.
>>
>> On Tue, May 12, 2020 at 5:16 PM Andreas Plesch <andreasplesch at gmail.com <mailto:andreasplesch at gmail.com>> wrote:
>> Hi,
>>
>> after some debugging I discovered another issue with x3d.py. It can be boiled down t o a few lines of code:
>>
>> import x3d.x3d as x
>>
>> my_scene = x.Scene()
>> group = x.Group()
>> my_scene.children.append(group)
>> print(my_scene.XML())
>>
>> => output
>> => <Scene>
>> => <Group/>
>> => </Scene>
>>
>> my_other_scene = x.Scene()
>> print(my_other_scene.XML())
>>
>> => output
>> => <Scene>
>> => <Group/>
>> => </Scene>
>>
>> I think my_other_scene should be empty but remembers the content of the first scene.
>> Can you reproduce that ?
>> On the other hand this works (in a new session):
>>
>> my_scene = x.Scene( children = [x.Group()] )
>> print(my_scene.XML())
>>
>> => output
>> => <Scene>
>> => <Group/>
>> => </Scene>
>>
>> my_other_scene = x.Scene()
>> print(my_other_scene.XML())
>>
>> => output
>> => <Scene>
>> => </Scene>
>>
>> --
>> Andreas Plesch
>> Waltham, MA 02453
>>
>>
>> --
>> Andreas Plesch
>> Waltham, MA 02453
>> _______________________________________________
>> x3d-public mailing list
>> x3d-public at web3d.org <mailto:x3d-public at web3d.org>
>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>
> _______________________________________________
> x3d-public mailing list
> x3d-public at web3d.org
> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20200512/bfbeebe7/attachment.html>
More information about the x3d-public
mailing list