Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    scope of optional arguments

    Scheduled Pinned Locked Moved PYTHON Development
    5 Posts 0 Posters 541 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      On 14/02/2013 at 09:29, xxxxxxxx wrote:

      Hi,

      I have got a stupid question I guess. It is actually not really c4d related, but I am asking here
      anyway. I have got a quite simple node token class. It basically just stores instances of its own 
      type.

      class rhTreeToken(object) :
      	def __init__(self, tokentype, children = None, subtype = None, value = None) :
      		if children == None:
      			self.Children = []
      		else:
      			self.Children   = children
      		self.Subtype    = subtype
      		self.Type       = tokentype
      		self.Value      = value
      	...
      

      When I write the same fragment this way,

      class rhTreeToken(object) :
      	def __init__(self, tokentype, children = [], subtype = None, value = None) :
        
      or
      	def __init__(self, tokentype, children = list(), subtype = None, value = None) :
      	...
      

      my whole node structure virtually explodes. I get an infinite recursion, data from other nodes
      appear as children of nodes they were never assigned to, the whole class seems to share the 
      memory for rhTreeToken.Children then.

      I suspect the optional arguments are not actually attached to the specific class  instance, but 
      stored somewhere in Pyhton, so that the empty list would be shared by all instances.  But i could 
      not find any proof / explanation for that, is that correct ?

      thanks for reading,

      a pretty confused,
      ferdinand

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 14/02/2013 at 09:44, xxxxxxxx wrote:

        Hi Ferdinand,

        the behavior is correct and is not actually related to the scope. The default-value for an argument
        is not created every-time the function is called, it is stored by reference.

        def magic(v, l=[]) :
            l.append(v)
            print "l:", l
          
        magic(0)
        magic(1)
        magic(2)
        magic(3)
        

        You can also look-up the default-values for a function:

        print magic.func_defaults
        

        Or even change:

        magic(0)
        magic(1)
        magic.func_defaults = ([],)
        magic(2)
        magic(3)
        

        You either have to keep with the None default-value, or copy the list for assignment.

               self.children = children[:]
        

        -Niklas

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 14/02/2013 at 09:57, xxxxxxxx wrote:

          hey thanks for the quick, answer.

          i did not knew that you could do this [:] . Just to be sure that i fully understand this -
          [:] is the list from start to end ?

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 14/02/2013 at 09:57, xxxxxxxx wrote:

            Hi Ferdinand,

            exactly, the list from start to end => copy of the list. 🙂

            You can also use the copy module if you find it more obvious. This also has the
            advantage, that it will be supported by more sequence-types than tuples or
            lists.

            import copy
            list_1 = ["foo", "bar"]
            list_2 = copy.copy(l_1)
            print list_1 == list_2 # True
            print list_1 is list_2 # False
            

            -Niklas

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 14/02/2013 at 10:14, xxxxxxxx wrote:

              no,  i like it, it is short, it is crpytic, chances are good, that i cannot my own code
              in two weeks from now. it is perfect 🙂

              1 Reply Last reply Reply Quote 0
              • First post
                Last post