Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

"Being against torture ought to be sort of a bipartisan thing." -- Karl Lehenbauer


devel / comp.lang.python / RE: Configuring an object via a dictionary

SubjectAuthor
o RE: Configuring an object via a dictionary<avi.e.gross

1
RE: Configuring an object via a dictionary

<mailman.115.1710710819.3452.python-list@python.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=29680&group=comp.lang.python#29680

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: <avi.e.gross@gmail.com>
Newsgroups: comp.lang.python
Subject: RE: Configuring an object via a dictionary
Date: Sun, 17 Mar 2024 17:26:51 -0400
Lines: 217
Message-ID: <mailman.115.1710710819.3452.python-list@python.org>
References: <b169e599-e81f-45ce-8e2a-7027b59a4627@tompassin.net>
<60E92E67-1412-4DE6-B330-495343107474@barrys-emacs.org>
<20240316230606.qjn5zepek645tsqq@hjp.at>
<98171cf7-c2ea-4496-8b68-fa9a8f247b3b@DancesWithMice.info>
<20240317151153.cgnsvd6hd7pb767r@hjp.at>
<002801da78b1$d3f982e0$7bec88a0$@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain;
charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de JmDhXBnFqoIAlsZDzAL72QLNEHwQdDcc5WGU01Iumvhw==
Cancel-Lock: sha1:0cfDNQDt/mf/qIqA5ZU6vtnzHuQ= sha256:6hDhyV5ikcpFUs8aWN7VhVY1ixRQWvTh3WIkkU8vKXk=
Return-Path: <avi.e.gross@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=csxNg4rj;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.000
X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'looks': 0.02; '(which':
0.04; '17,': 0.04; 'argument': 0.04; 'def': 0.04; '(for': 0.05;
'containing': 0.05; 'fairly': 0.05; 'usage': 0.05; 'variable':
0.05; '"hello': 0.07; 'arrays': 0.07; 'mar': 0.07; 'parent': 0.07;
'tests': 0.07; 'van': 0.07; 'wanting': 0.07; 'python.': 0.08;
'configuring': 0.09; 'else:': 0.09; 'enough.': 0.09;
'environments': 0.09; 'fails': 0.09; 'meant': 0.09; 'obviously,':
0.09; 'received:108': 0.09; 'set,': 0.09; 'theory': 0.09;
'values.': 0.09; 'syntax': 0.15; '"creative': 0.16; '2024': 0.16;
'__/': 0.16; 'assuming': 0.16; 'barry': 0.16; 'below).': 0.16;
'beta': 0.16; 'challenge!"': 0.16; 'column': 0.16; 'declared':
0.16; 'default.': 0.16; 'expects': 0.16; 'hand,': 0.16;
'hjp@hjp.at': 0.16; 'holzer': 0.16; 'idiom': 0.16; 'ignored':
0.16; 'interpreter': 0.16; 'neal': 0.16; 'overlap': 0.16;
'present,': 0.16; 'reality.': 0.16; 'region.': 0.16; 'self.name':
0.16; 'semantics': 0.16; 'stross,': 0.16; 'structures': 0.16;
'subset': 0.16; 'typing': 0.16; 'unpacking': 0.16; 'url-
ip:212.17.106/24': 0.16; 'url-ip:212.17/16': 0.16; 'url:hjp':
0.16; 'useful.': 0.16; 'variables,': 0.16; 'ways.': 0.16; '|_|_)':
0.16; 'wrote:': 0.16; 'problem': 0.16; 'python': 0.16; 'values':
0.17; 'instead': 0.17; 'message-id:@gmail.com': 0.18; 'implement':
0.19; 'to:addr:python-list': 0.20; 'language': 0.21; "i've": 0.22;
'languages': 0.22; 'code': 0.23; 'goal': 0.23; 'lines': 0.23;
'anything': 0.25; 'skip:- 10': 0.25; 'programming': 0.25;
'object': 0.26; "isn't": 0.27; 'leave': 0.27; 'else': 0.27;
'local': 0.27; 'bit': 0.27; 'function': 0.27; '>>>': 0.28; 'fact':
0.28; 'mostly': 0.28; 'purpose': 0.28; 'sense': 0.28; 'thinking':
0.28; 'keeping': 0.28; 'environment': 0.29; 'packages': 0.31;
'seem': 0.31; 'default': 0.31; 'looked': 0.31; 'program': 0.31;
'think': 0.32; 'question': 0.32; 'course.': 0.32; 'empty': 0.32;
'gotten': 0.32; 'objects': 0.32; 'python-list': 0.32; 'split':
0.32; 'unknown': 0.32; 'but': 0.32; 'there': 0.33; 'body': 0.67;
'caught': 0.67; 'choose': 0.67; 'that,': 0.67; 'exactly': 0.68;
'items': 0.68; 'matter': 0.68; 'order': 0.69; 'sequence': 0.69;
'type:': 0.69; 'url-ip:212/8': 0.69; 'varying': 0.69; 'within':
0.69; 'ignore': 0.71; 'production': 0.71; 'global': 0.73;
'features': 0.75; 'combination': 0.76; 'languages,': 0.76;
'sent:': 0.78; 'dangerous': 0.81; 'names,': 0.81; 'left': 0.83;
'editing': 0.84; 'extra': 0.84; 'known': 0.84; 'debate': 0.84;
'delays': 0.84; 'delta,': 0.84; 'exactly.': 0.84; 'indices': 0.84;
'pairs': 0.84; 'want.': 0.84; 'behind': 0.88; 'consisting': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20230601; t=1710710815; x=1711315615; darn=python.org;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:from:to:cc:subject:date:message-id:reply-to;
bh=HdMGvz21pBWEv54FM5xXEbsg+b3v/MRLC9n5eZ1w8gU=;
b=csxNg4rjTC6MmYLWBo7McZvJ7zhnoZhI7HttezWZBm5PkTGojTIU3tTQ6buhhXFelx
XTwNqreJQTYfcfOVPHC9wwCWMIr4gzLmCVMOYBFaMWxdUebrQGquc2Qe9/YP0eWugBX9
2jwvX8tdrcskN7q7UcfxJiGWYUVmShmoWicsRx/KwDCBPtDT7dTBsBzC7hXsT4vaUge4
hJ7mgZctDw/cBwqQHJK4zh7uXr6TGXV9fTh8HhRLp8bNyLtadcfRgu7j46Lp+sdfiY0z
3KrPqYKdw41UH5PiGbzGCub7fwQnL0kE0tGAfiVYYa4ZmnKIn5kcg5V7FCEpdvv1fMyU
xv/Q==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20230601; t=1710710815; x=1711315615;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=HdMGvz21pBWEv54FM5xXEbsg+b3v/MRLC9n5eZ1w8gU=;
b=LfhdZSy/HX260v378KIhtjS4jy6gmxixOs7C1uLVGqQkQ17s0X5yBhhQAAalrmJm/C
jftEW88tOazLI4H5Q0rYVZw76aKvztVqAgmt8SL5+RaBCyTTi7WC+7ULud6ebIZSh6hb
+4kLHsv3EaFgcrYfYo5szZiSDPPoYlVzIFxJ++nHh1mpAvQ3bycOr3RrYrBJKSDszK01
w/MfUJNrhxaia/jMRhgdfUvL6vbCO+jpkvacDctCxeQm2sVoVBFo5P/Ou8auigNcbHaN
MJfDH7kxkaV5Jy5T+G7HORHNcJMTzh++4CPiRitf2lynF0OGDuwTvtNnUteW3Zutq0Z4
fkRw==
X-Gm-Message-State: AOJu0Yytgz8k7fRMReCAUCwmldpihXqyCKVsw0KnUV5sTaceFjViSGMH
eqzJlNCW8wsXUsQZnJD8exO149RdHsMsPqMHe45LWZ4kRyzvvlROvyyN1yDi
X-Google-Smtp-Source: AGHT+IFoxj887y3qTSUlod40dks+spgLKQ6Wo4tkgpQTiFT+Cy1csuN/owf/E5vDbppzEooWAwqODQ==
X-Received: by 2002:a05:620a:15b0:b0:788:2e8a:172e with SMTP id
f16-20020a05620a15b000b007882e8a172emr11359828qkk.36.1710710815287;
Sun, 17 Mar 2024 14:26:55 -0700 (PDT)
In-Reply-To: <20240317151153.cgnsvd6hd7pb767r@hjp.at>
X-Mailer: Microsoft Outlook 16.0
Content-Language: en-us
Thread-Index: AQMa6or+p3yTSsOF4rT4V/3CN9y7zQHarj2CAXcoGVcA+++/0wGwTYjSrouJpBA=
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <002801da78b1$d3f982e0$7bec88a0$@gmail.com>
X-Mailman-Original-References: <b169e599-e81f-45ce-8e2a-7027b59a4627@tompassin.net>
<60E92E67-1412-4DE6-B330-495343107474@barrys-emacs.org>
<20240316230606.qjn5zepek645tsqq@hjp.at>
<98171cf7-c2ea-4496-8b68-fa9a8f247b3b@DancesWithMice.info>
<20240317151153.cgnsvd6hd7pb767r@hjp.at>
 by: <avi.e.gross@gmail.com> - Sun, 17 Mar 2024 21:26 UTC

If we are bringing up other languages, let's return to what was part of the original question.

How van a dictionary be used in python if your goal is to sort of use it to instantiate it into a set of variables and values inside the local or global or other namespaces? Can we learn anything from other programming languages with other paradigms?

I was thinking that in one sense, python has other kinds of collections such as a class or class member with internal variables that also has some features similar enough.

I mean if I were to call a function with one argument being a dictionary like {"a":1, "c": 3} where in theory any number of similar key value pairs might exist or not be present, then the question sounded like a request to create variables, in this case a, and c, that hold those values. I will not debate the wisdom of doing that, of course. Nor will I debate what should happen if some of those variable names are already in use. OK?

There are ways to do this albeit some are a tad obscure such as taking a printable representation of the dictionary and editing it and feeding that to an eval.

But could you serve a similar purpose by passing an object containing varying internal fields (or methods) and values including some of the dataclasses Dave Neal is highlighting? Is there some overlap with using dictionaries?

In Javascript, I would say they have a very different view in which all kinds of things overlap and their objects can even implement what others might call arrays albeit a tad weirder like allowing missing indices and ignoring non-numeric indices for some purposes. Someone may wish to chime in if people can and do take such objects passed in and split them into individual variables as requested.

What I wanted to mention is some philosophical issues in the R language in which the default language used other data structures to loosely support what dictionaries often do in python. They have named lists where components optionally can have a name as in list(a=5, "b"=6, 7, "hello world") and they have data structures called environments. Loosely, an environment is a set of name=value pairs and is pretty much like a dictionary and is mostly used behind the scenes as the interpreter searches for variable names in a sequence of environments such as the parent environment. But you can use environments all over the place on purpose and as noted, a named list simulates an environment.

So a fairly common usage when using base R is to take a data.frame (which is at first approximation a list of named vectors all the same length) and want to work with the column names without extra typing. If I had a data.frame that looked like mydf <- data.frame(a=1:3, b=3:1) then if I wanted to add corresponding entries, I might type:

result <- mydf$a + mydf$b

inside a with statement, an environment is put on the stack consisting of the contents of mydf and you can now use things like:

result <- with(mydf, a+b)

There is more but the point is for those who hate the extra typing of long names, this can be useful and a tad dangerous if the variable names are not unique.

But as R delays evaluation in various ways, a similar style has evolved in an assortment of packages to the point where I often program in a style that looks like:

result <-
mydf |>
mutate(newcol = a+b, doubled = 2*newcol, ...)

The point is that all kinds of things that seem like local variables can be used as if they had been declared withing some environment but that are not available once you leave that region.

So perhaps there is some validity in a request to be able to just pass an argument as a dictionary in python and have it unpacked.

In actuality, I wonder if the OP is aware of the unpacking functionality you can get using **dict in a function invocation.

Say you have a function that expects any combination of three variables called the unoriginal names of alpha/beta/gamma and you want to call it with a dictionary that contains any subset of those same keys and nothing else:

mydict = {"alpha":5, "beta":6}

def unpacked(alpha=None, beta=None, gamma=None):
print(alpha if alpha != None else "No alpha")
print(beta if beta != None else "No beta")
print(gamma if gamma != None else "No gamma")

If I now call unpacked with ** mydict:

>>> unpacked(**mydict)
5 6
No gamma

Within the body of that function, arguably, I can tell if something was passed or not, assuming None or any other sentinel I choose is not used except in setting the default.

And if you add other unknown names, like delta, they seem to be ignored without harmful effects or can be caught in other ways.

>>> unpacked({"gamma":7, "delta":8})
{'gamma': 7, 'delta': 8}
No beta
No gamma

So given a function similar to this, and you wanting LOCAL variables set, how would this do if you wanted these three or any number, and in a row:

mydict = {"beta":6, "alpha":5}

def dict_to_vars(alpha=None, beta=None, gamma=None):
return(alpha, beta, gamma)

alpha, beta, gamma = dict_to_vars(**mydict)

The result works no matter what order you have added to the dictionary as long as you know exactly which N you want. Obviously, you may not be thrilled with None as a value and can add code to remove empty variables after they have been instantiated.

>>> alpha
5 >>> beta
6 >>> gamma
>>>

If you want to ignore some entries, use _ in your list of places for items you want to toss.

alpha, _, _ = dict_to_vars(**mydict)

The above is really just keeping alpha.

Of course if the possible keys are not known in advance, this does not work but other languages that allow this may be better for your purpose.

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Peter J. Holzer via Python-list
Sent: Sunday, March 17, 2024 11:12 AM
To: python-list@python.org
Subject: Re: Configuring an object via a dictionary

On 2024-03-17 17:15:32 +1300, dn via Python-list wrote:
> On 17/03/24 12:06, Peter J. Holzer via Python-list wrote:
> > On 2024-03-16 08:15:19 +0000, Barry via Python-list wrote:
> > > > On 15 Mar 2024, at 19:51, Thomas Passin via Python-list <python-list@python.org> wrote:
> > > > I've always like writing using the "or" form and have never gotten bit
> > >
> > > I, on the other hand, had to fix a production problem that using “or” introducted.
> > > I avoid this idiom because it fails on falsy values.
> >
> > Perl has a // operator (pronounced "err"), which works like || (or),
> > except that it tests whether the left side is defined (not None in
> > Python terms) instead of truthy. This still isn't bulletproof but I've
> > found it very handy.
>
>
> So, if starting from:
>
> def method( self, name=None, ):
>
> rather than:
>
> self.name = name if name else default_value
>
> ie
>
> self.name = name if name is True else default_value

These two lines don't have the same meaning (for the reason you outlined
below). The second line is also not very useful.

> the more precise:
>
> self.name = name if name is not None or default_value
>
> or:
>
> self.name = default_value if name is None or name

Those are syntax errors. I think you meant to write "else" instead of
"or".

Yes, exactly. That's the semantic of Perl's // operator.

JavaScript has a ?? operator with similar semantics (slightly
complicated by the fact that JavaScript has two "nullish" values).

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor