Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #74442 > unrolled thread

initializing "parameters" class in Python only once?

Started byCatherine M Moroney <Catherine.M.Moroney@jpl.nasa.gov>
First post2014-07-14 15:24 -0700
Last post2014-07-16 21:43 -0700
Articles 8 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  initializing "parameters" class in Python only once? Catherine M Moroney <Catherine.M.Moroney@jpl.nasa.gov> - 2014-07-14 15:24 -0700
    Re: initializing "parameters" class in Python only once? Rob Gaddi <rgaddi@technologyhighland.invalid> - 2014-07-14 16:07 -0700
    Re: initializing "parameters" class in Python only once? Chris Kaynor <ckaynor@zindagigames.com> - 2014-07-14 16:21 -0700
    Re: initializing "parameters" class in Python only once? Ben Finney <ben@benfinney.id.au> - 2014-07-15 10:04 +1000
    Re: initializing "parameters" class in Python only once? Steven D'Aprano <steve@pearwood.info> - 2014-07-15 05:28 +0000
      Re: initializing "parameters" class in Python only once? alex23 <wuwei23@gmail.com> - 2014-07-17 13:35 +1000
        Re: initializing "parameters" class in Python only once? Steven D'Aprano <steve@pearwood.info> - 2014-07-17 04:27 +0000
        Re: initializing "parameters" class in Python only once? Ethan Furman <ethan@stoneleaf.us> - 2014-07-16 21:43 -0700

#74442 — initializing "parameters" class in Python only once?

FromCatherine M Moroney <Catherine.M.Moroney@jpl.nasa.gov>
Date2014-07-14 15:24 -0700
Subjectinitializing "parameters" class in Python only once?
Message-ID<53C4589A.9040109@jpl.nasa.gov>
Hello,

Pardon me for not using the proper Python language terms, but I hope 
that people can still understand the question:

The problem:  I'm writing a large Python program and I have a bunch of
parameters (whose values are static) that I want to make available to
the rest of the code with minimum overhead and duplicate processing.

I think that the simplest way would be to create a file called 
"Params.py" and then simply have statements like a = 1, b = 2, etc.
in there (no classes, no methods, just a bunch of declarations).  But, 
some of these static parameters have to be calculated rather than simply 
hard-coded.

I thought of creating a class called Params and having a bunch of
methods (decorated with @classmethod) that set/calculate the value of
all the parameters.  Easy enough, but then I have to create a Params
object in every source file that uses these parameters, and that seems
wasteful.

The actual scope of the problem is very small, so memory/cpu time is not
an issue.  I'm just looking for the most pythonic/elegant way of doing this.

What is the recommended way of passing a bunch of static (hard-coded and 
calculated) parameters to various parts of the code?

Thank you for any advice,

Catherine

[toc] | [next] | [standalone]


#74443

FromRob Gaddi <rgaddi@technologyhighland.invalid>
Date2014-07-14 16:07 -0700
Message-ID<20140714160704.11ac7b4d@rg.highlandtechnology.com>
In reply to#74442
On Mon, 14 Jul 2014 15:24:26 -0700
Catherine M Moroney <Catherine.M.Moroney@jpl.nasa.gov> wrote:

> Hello,
> 
> Pardon me for not using the proper Python language terms, but I hope 
> that people can still understand the question:
> 
> The problem:  I'm writing a large Python program and I have a bunch of
> parameters (whose values are static) that I want to make available to
> the rest of the code with minimum overhead and duplicate processing.
> 
> I think that the simplest way would be to create a file called 
> "Params.py" and then simply have statements like a = 1, b = 2, etc.
> in there (no classes, no methods, just a bunch of declarations).  But, 
> some of these static parameters have to be calculated rather than simply 
> hard-coded.
> 
> I thought of creating a class called Params and having a bunch of
> methods (decorated with @classmethod) that set/calculate the value of
> all the parameters.  Easy enough, but then I have to create a Params
> object in every source file that uses these parameters, and that seems
> wasteful.
> 
> The actual scope of the problem is very small, so memory/cpu time is not
> an issue.  I'm just looking for the most pythonic/elegant way of doing this.
> 
> What is the recommended way of passing a bunch of static (hard-coded and 
> calculated) parameters to various parts of the code?
> 
> Thank you for any advice,
> 
> Catherine

You're 90% of the way there.  You can just create params.py, fill it
with statements that are either hard-coded or calculated as necessary,
and import params from all over the rest of the program.  Once the
interpreter has imported it for the first time, everyone else just gets
a link to the same instance of the module rather than running it all
over and over again.

-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.

[toc] | [prev] | [next] | [standalone]


#74444

FromChris Kaynor <ckaynor@zindagigames.com>
Date2014-07-14 16:21 -0700
Message-ID<mailman.11811.1405380114.18130.python-list@python.org>
In reply to#74442

[Multipart message — attachments visible in raw view] — view raw

On Mon, Jul 14, 2014 at 3:24 PM, Catherine M Moroney <
Catherine.M.Moroney@jpl.nasa.gov> wrote:

> Hello,
>
> Pardon me for not using the proper Python language terms, but I hope that
> people can still understand the question:
>
> The problem:  I'm writing a large Python program and I have a bunch of
> parameters (whose values are static) that I want to make available to
> the rest of the code with minimum overhead and duplicate processing.
>
> I think that the simplest way would be to create a file called "Params.py"
> and then simply have statements like a = 1, b = 2, etc.
> in there (no classes, no methods, just a bunch of declarations).  But,
> some of these static parameters have to be calculated rather than simply
> hard-coded.
>

Within a module (such as "Params.py"), you can put any statements or code
you want, without needing classes or functions. Depending on the complexity
of the calculations, you may want to put some of the functionality into
functions, which could then be run on import (just put the function call at
the bottom of the module file).

The interpreter will take care to only import one copy, with the exception
of if the Params.py file is accessible from multiple paths in sys.path
(generally not an issue).

For example, the following is a valid module (untested):
# Params.py
a = 1
b = 5
c = a * b + 42
d = c - b
# End Params.Py

You could also go farther and read external configuration files at the root
scope. The main thing to remember is that all intermediate variables will
be visible outside, and thus should be prefixed with an underscore
(Python's standard for private).

I thought of creating a class called Params and having a bunch of
> methods (decorated with @classmethod) that set/calculate the value of
> all the parameters.  Easy enough, but then I have to create a Params
> object in every source file that uses these parameters, and that seems
> wasteful.
>

If all the methods of a class as decorated with @classmethod or
@staticmethod, and all variables are declared on the class, and not inside
of any non-class/static methods (include __init__), you would not need to
create instances of the object.

For example, if you have a class like follows (untested):

class Params():
    myVar = 0
    @classmethod
    def myMethod(cls):
        cls.myVar += 1
        return cls.myVar

you can access them without an instance, by using Params.myVar or
Params.myMethod().


> The actual scope of the problem is very small, so memory/cpu time is not
> an issue.  I'm just looking for the most pythonic/elegant way of doing
> this.
>

For most configuration, I would recommend using a combination of the above.
Create the module and place some configuration variables inside the module
directly. Use classes (which shouldn't be instantiated) for namespacing. If
you start to get a LOT of parameters, you may also want to consider making
the entire params a package (folder/directory) with multiple modules and
possibly classes, however that is likely overkill.

Note that, in any case, I would recommend treating the parameters as
constants, meaning do not change their values, except during the
initialization of the parameters module. This is mostly to ensure
thread-safety and prevent difficult to track bugs.


>
> What is the recommended way of passing a bunch of static (hard-coded and
> calculated) parameters to various parts of the code?
>
> Thank you for any advice,
>
> Catherine
> --
> https://mail.python.org/mailman/listinfo/python-list
>

[toc] | [prev] | [next] | [standalone]


#74448

FromBen Finney <ben@benfinney.id.au>
Date2014-07-15 10:04 +1000
Message-ID<mailman.11815.1405382658.18130.python-list@python.org>
In reply to#74442
Catherine M Moroney <Catherine.M.Moroney@jpl.nasa.gov> writes:

> The problem:  I'm writing a large Python program and I have a bunch of
> parameters (whose values are static) that I want to make available to
> the rest of the code with minimum overhead and duplicate processing.

Better than putting these in executable code, then, is to put them in a
configuration file read as *data*, not code, when your program starts.

Look at the ‘configparser’ module from the Python standard library
<URL:https://docs.python.org/3/library/configparser.html> for a robust
way to read run-time configuration parameters from a non-executable file.

The result of reading the config file (or set of them, if your use case
is complex enough) is an object containing the parameters, which can be
interrogated as normal by getting its attributes. See the documentation
for examples.

-- 
 \            “[T]he great menace to progress is not ignorance but the |
  `\           illusion of knowledge.” —Daniel J. Boorstin, historian, |
_o__)                                                        1914–2004 |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#74468

FromSteven D'Aprano <steve@pearwood.info>
Date2014-07-15 05:28 +0000
Message-ID<53c4bbf2$0$2746$c3e8da3$76491128@news.astraweb.com>
In reply to#74442
On Mon, 14 Jul 2014 15:24:26 -0700, Catherine M Moroney wrote:

> The problem:  I'm writing a large Python program and I have a bunch of
> parameters (whose values are static) that I want to make available to
> the rest of the code with minimum overhead and duplicate processing.
> 
> I think that the simplest way would be to create a file called
> "Params.py" and then simply have statements like a = 1, b = 2, etc. in
> there (no classes, no methods, just a bunch of declarations).

That sounds exactly right to me.


> But, some
> of these static parameters have to be calculated rather than simply
> hard-coded.

I don't think that should be a problem. You can include calculations:

a = 1
b = 2
c = a**2 + b**2 - a + 1


The only difficulty is if you want those values to be calculated on 
demand, rather than at program startup. If that's the case, I think the 
best solution is to turn them into functions:

def c():
    return a**2 + b**2 - a + 1


This, sadly, requires you to tell the difference between params that 
should be constants and those which should be function calls. If that is 
a serious problem, you should consider a singleton class with properties, 
but if the simpler solution works for you, stick to the simpler solution!


> I thought of creating a class called Params and having a bunch of
> methods (decorated with @classmethod) that set/calculate the value of
> all the parameters.  Easy enough, but then I have to create a Params
> object in every source file that uses these parameters, and that seems
> wasteful.

I don't think that Params with class methods is the best solution. I 
would do something like this:

# === module params.py ===
class Params(object):
    a = 1
    b = 2

    @property
    def c(self):
        return self.a**2 + self.b**2 - self.a + 1


params = Params()
del Params  # hide the class



Then callers just say:

from params import params
print params.c


All modules now see the same params instance, so it is (almost) a 
singleton.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#74607

Fromalex23 <wuwei23@gmail.com>
Date2014-07-17 13:35 +1000
Message-ID<lq7g9u$rmh$1@dont-email.me>
In reply to#74468
On 15/07/2014 3:28 PM, Steven D'Aprano wrote:
> # === module params.py ===
> class Params(object):
>      a = 1
>      b = 2
>
>      @property
>      def c(self):
>          return self.a**2 + self.b**2 - self.a + 1
>
> params = Params()
> del Params  # hide the class
>
>
> Then callers just say:
>
> from params import params
> print params.c

I'd replace the instantiation & deletion of the class in params.py with:

     import sys
     sys.modules[__name__] = Params()

..and replace the module itself with the parameter object. I'd also add:

     __file__ = __file__

...to the class definition to help with debugging. But this is really 
just bikeshedding.

It's a shame the property decorator doesn't work at the module level, 
though.

[toc] | [prev] | [next] | [standalone]


#74613

FromSteven D'Aprano <steve@pearwood.info>
Date2014-07-17 04:27 +0000
Message-ID<53c750ce$0$29897$c3e8da3$5496439d@news.astraweb.com>
In reply to#74607
On Thu, 17 Jul 2014 13:35:24 +1000, alex23 wrote:

> It's a shame the property decorator doesn't work at the module level,
> though.

Not necessarily the property decorator, but some sort of computed 
variable would be nice.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#74620

FromEthan Furman <ethan@stoneleaf.us>
Date2014-07-16 21:43 -0700
Message-ID<mailman.11915.1405576296.18130.python-list@python.org>
In reply to#74607
On 07/16/2014 08:35 PM, alex23 wrote:
> On 15/07/2014 3:28 PM, Steven D'Aprano wrote:
>> # === module params.py ===
>> class Params(object):
>>      a = 1
>>      b = 2
>>
>>      @property
>>      def c(self):
>>          return self.a**2 + self.b**2 - self.a + 1
>>
>> params = Params()
>> del Params  # hide the class
>>
>>
>> Then callers just say:
>>
>> from params import params
>> print params.c
>
> I'd replace the instantiation & deletion of the class in params.py with:
>
>      import sys
>      sys.modules[__name__] = Params()
>
> ..and replace the module itself with the parameter object. I'd also add:
>
>      __file__ = __file__
>
> ...to the class definition to help with debugging. But this is really just bikeshedding.

Just make sure the 'sys.modules' assignment happens at the *end* of params.py.

--
~Ethan~

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web