[Tutor] use of dict() function

dn PythonList at DancesWithMice.info
Wed Jun 12 14:45:51 EDT 2024


On 13/06/24 05:58, Alex Kleider wrote:
> On the contrary, I have _not_ figured it out!

Sorry to hear. Did you continue by questioning earlier reply?

Given the two responses, was the question well-expressed or has it 
changed since? Both  addressed "Is there an explanation???".


> My goal is to have a way of creating an object (a class instance,) in
> this case a dict, without there being any chance of the original dict
> (the parameter of the init call) being modified.

The common issue experienced when moving to Python from another 
programming language is that identifiers are only pointing to memory. Thus:

 >>> a = { key: value for key, value in enumerate( "abcde" ) }
 >>> b = a
 >>> b
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}

result in a and b pointing to the same dictionary. Any change made to 
one will 'appear' as a change to the other.

 >>> a[ 0 ] = 'z'
 >>> b
{0: 'z', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}


Choices to make a distinct copy of the original dict:

c = dict( a )
d = a.copy()
import copy; e = copy.deepcopy( a )


For proof, use id( ... ) to verify if a, b, c, d, and e point to the 
same or separate 'memory addresses'...

(many of the above techniques, including help() and id(), also stated in 
Stephen's article)


> (... and also to have the additional feature of being able to "call"
> the instance and get the dict formatted as specified by the string
> parameter.)

Please provide examples of the expected behavior/what would like to 
achieve...


> Using the dict function provides the mechanism to do the first part
> without the need of a class.
> Must I assign to an intermediary identifier rather than to self itself?
> i.e. self.value = dict(mapping)
 > and then access the mapping using "instance.value"  rather than
 > "instance" by itself?

What were the results when you tried the two solutions provided earlier? 
Do they illustrate answers to this question?


The article did not discuss sub-classing dict - only using the dict() 
function as a constructor (IIRC). Sub-classing Python's types can easily 
(quickly?) cause this sort of head-scratching. From 
https://docs.python.org/3/library/collections.html#collections.UserDict

UserDict objects
The class, UserDict acts as a wrapper around dictionary objects. The 
need for this class has been partially supplanted by the ability to 
subclass directly from dict; however, this class can be easier to work 
with because the underlying dictionary is accessible as an attribute.

- which would grant the instance.value option, if that's your preference.



> Thanks for your input.
> Alex
> 
> 
> On Wed, Jun 12, 2024 at 1:11 AM Peter Otten via Tutor <tutor at python.org> wrote:
>>
>> On 03/06/2024 04:44, Alex Kleider wrote:
>>
>> You may have figured it out in the mean time, but note that
>>
>>> class Rec1(dict):
>>>       def __init__(self, rec):
>>>           self = dict(rec)
>>
>> assigning to self has no effect (on the class). self is just a name that
>> you can bind anything to:
>>
>>   >>> class Stuff:
>>          def __init__(self):
>>                  print(f"before: {self})"
>>                  self = 42
>>                  print(f"after: {self}")
>>
>> SyntaxError: invalid syntax
>>   >>> class Stuff:
>>          def __init__(self):
>>                  print(f"before: {self})")
>>                  self = 42
>>                  print(f"after: {self}")
>>
>>
>>   >>> Stuff()
>> before: <__main__.Stuff object at 0x02BDD5B0>)
>> after: 42
>> <__main__.Stuff object at 0x02BDD5B0>
>>
>> So you are basically overwriting dict.__init__() with a no-op
>> Rec1.__init__(). The easiest fix is to omit the initializer:
>>
>>   >>> class R(dict):
>>          def __call__(self, fmt): return fmt.format_map(self)
>>
>>
>>   >>> r = R({"a": 1}, b=2)
>>   >>> r["c"] = 3
>>   >>> r
>> {'a': 1, 'b': 2, 'c': 3}
>>   >>> r("{a} + {b} = {c}")
>> '1 + 2 = 3'
>>
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
> 
> 
> 
> --
> alex at kleider.ca  (he/him)
> (sent from my current gizmo)
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

-- 
Regards,
=dn


More information about the Tutor mailing list