ethical questions about global variables

G

Giampaolo Rodola'

Hi,
in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

In first place I've never liked global variables too much and always
preferred per-class-instance variables instead.
The problem in my case is that I have to use such variable in two
separated classes: FTPHandler and VirtualFileSystem. Also, I want that
for no reason one class uses times in GMT and the other one local
times.

Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION. What am
I supposed to do about it?

Thanks in advance for any comment.


--- Giampaolo
http://code.google.com/p/pyftpdlib/
 
J

James Mills

Hi,
in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

In first place I've never liked global variables too much and always
preferred per-class-instance variables instead.
The problem in my case is that I have to use such variable in two
separated classes: FTPHandler and VirtualFileSystem. Also, I want that
for no reason one class uses times in GMT and the other one local
times.

Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION. What am
I supposed to do about it?

Thanks in advance for any comment.

You could always use a "config" object
that you pass around to your other objects.

--JamesMills
 
R

rurpy

in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

In first place I've never liked global variables too much and always
preferred per-class-instance variables instead.

By "per-class-instance variables", you are talking
about instance attributes? I.e. "self.use_gmt_times"?
I don't see much difference between global variables
and instance attributes. One of the main problems
that make global variables bad is that they can be
referenced and set anywhere in a program, so it can
be very difficult, when one finds a global has a
wrong value at some point, to figure out how it got
that value.

Consider the following:

~~~ Snippet 1 ~~~
#my_module
def func1():
global A
A = 1
def func2
global A
A = 2
def func3
global A #Yes, this is redundant
print A

~~~ Snippet 2 ~~~
class my_class:
def func1():
self.A = 1
def func2
self.A = 2
def func3
print self.A

What's the difference between snippet 1 and
snippet 2? In the snippet 1, one says "global A";
in the snippet 2, "self." -- in this case it is
just a spelling difference. If globals are "evil"
then so must be the isomorphic use of attributes
in snippet 2.

I suppose one can say that classes are generally
smaller than modules so that the "globalish" aspect
of attributes is acceptable. But then one must
conclude that the prohibition against using globals
also applies to using instance attributes in large
classes. Or conversely, that globals are perfectly
acceptable, even desirable, in small modules.

Note also that the common workaround to eliminate
globals, passing them as arguments, doesn't really
change anything either:

#my_module
class Config: pass
config = Config()

def func1(state):
config.A = 1
def func2(state)
config.A = 2
def func3(state)
print config.A

In other words, it is not the "global" keyword
that causes problems, it is the anti-pattern
of making a variable accessible in a read/write
manner to a large number of functions without
much control over who can change it or when.
That anti-pattern can exist with globals, with
instance attributes, or with function arguments.
Simply avoiding globals is not sufficient to avoid
the anti-pattern.
The problem in my case is that I have to use such variable in two
separated classes: FTPHandler and VirtualFileSystem. Also, I want that
for no reason one class uses times in GMT and the other one local
times.

Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION. What am
I supposed to do about it?

I generally use an initial capital letter for my
global variables. I think it is useful to have
some signal that a variable may be set outside
the scope of the local function/method.
 
R

rurpy

#my_module
class Config: pass
config = Config()

def func1(state):
config.A = 1
def func2(state)
config.A = 2
def func3(state)
print config.A

That of course should have been:

def func1(config):
config.A = 1
def func2(config)
config.A = 2
def func3(config)
print config.A
 
M

Michele Simionato

Hi,
in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

Global variables have a bad reputation, but they are not
so bad in Python. Notice that:

1. global variables in Python are local to the module they
are defined in;

2. class names and module names are usually global variables
and nobody complains about that.

3. if you use an ALL_CAPS convention it is quite quite clear
that you are using a global variable.

Actually the ALL_CAPS convention is for constants, but
sometimes I use it for configuration variables too, if
they are set at the beginning and they are never changed
during the running of the program. If you have more than
a single global, it makes sense to introduce a configuration
object, as others have said (this is how typically work)
but if you have a single parameter the confuguration
object is not worth the effort, IMO.

M. Simionato
 
B

Bruno Desthuilliers

Giampaolo Rodola' a écrit :
Hi,
in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

In first place I've never liked global variables too much and always
preferred per-class-instance variables instead.
The problem in my case is that I have to use such variable in two
separated classes: FTPHandler and VirtualFileSystem. Also, I want that
for no reason one class uses times in GMT and the other one local
times.

Looks like it's more a configuration variable than a global. IOW, it's
not supposed to change during execution.
Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION.

ALL_UPPER_NAMES are pseudo-constants - IOW, they are really variables
but are by convention considered as constants.

HTH
 
G

Gabriel Genellina

Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION. What am
I supposed to do about it?

Are you sure those UPPER_CASE names you've seen are actually variables? or
constants like:

CRLF = '\r\n'

(ok, it's not a true "constant" because the language doesn't prevent you
from modifying it... but the "intended usage" is to be a constant)
 
G

Giampaolo Rodola'

Global variables have a bad reputation, but they are not
so bad in Python. Notice that:

1. global variables in Python are local to the module they
   are defined in;

2. class names and module names are usually global variables
   and nobody complains about that.

3. if you use an ALL_CAPS convention it is quite quite clear
   that you are using a global variable.

Actually the ALL_CAPS convention is for constants, but
sometimes I use it for configuration variables too, if
they are set at the beginning and they are never changed
during the running of the program. If you have more than
a single global, it makes sense to introduce a configuration
object, as others have said (this is how typically work)
but if you have a single parameter the confuguration
object is not worth the effort, IMO.

                 M. Simionato

No, all the other "configurable" variables are offered as class
attributes.


--- Giampaolo
http://code.google.com/p/pyftpdlib/
 
Y

Yinon Ehrlich

Hi,
in a module of mine (ftpserver.py) I'd want to add a (boolean) global
variable named "use_gmt_times" to decide whether the server has to
return times in GMT or localtime but I'm not sure if it is a good idea
because of the "ethical" doubts I'm gonna write below.

In first place I've never liked global variables too much and always
preferred per-class-instance variables instead.
The problem in my case is that I have to use such variable in two
separated classes: FTPHandler and VirtualFileSystem. Also, I want that
for no reason one class uses times in GMT and the other one local
times.

Another doubt is the naming convention. PEP-8 states that global
variables should use the lower_case_naming_convention but I've seen a
lot of library module using the UPPER_CASE_NAMING_CONVENTION. What am
I supposed to do about it?

Thanks in advance for any comment.

--- Giampaolohttp://code.google.com/p/pyftpdlib/

Note also that PEP-8 states that "_single_leading_underscore... from M
import *" does not import objects whose name starts with an
underscore"
 
I

ianaré

For anything more complicated than a simple script, I find it easier
to use some sort of config object. This could be a simple dictionnary
type class, where the values can be set/retrieved by the other classes
directly, or a more elaborate class including functions to set/
retrieve the variables. This way setting/retrieving can be 'smart' --
possibly looking at other variables, program states, thread count,
whatever, for the requested config option. It also allows for a lot of
expansion down the line if need be, rather than dealing with all sorts
of global variables floating around - which gets annoying pretty
quickly.
 
G

Giampaolo Rodola'

For anything more complicated than a simple script, I find it easier
to use some sort of config object. This could be a simple dictionnary
type class, where the values can be set/retrieved by the other classes
directly, or a more elaborate class including functions to set/
retrieve the variables. This way setting/retrieving can be 'smart' --
possibly looking at other variables, program states, thread count,
whatever, for the requested config option. It also allows for a lot of
expansion down the line if need be, rather than dealing with all sorts
of global variables floating around - which gets annoying pretty
quickly.







- Mostra testo citato -

All the modificable options the library has acquired so far consist of
class attributes and I'm ok with that.
The only option that should be global is "use_gmt_times" because it is
supposed to be used in two classes and I want that both of them use
the same parameter.
Using a Config class for a single option like "use_gmt_times" is not
worth the effort, IMO.


--- Giampaolo
http://code.google.com/p/pyftpdlib/
 
Ð

Дамјан ГеоргиевÑки

By "per-class-instance variables", you are talking
about instance attributes? I.e. "self.use_gmt_times"?
I don't see much difference between global variables
and instance attributes.

using global variable in modules makes the module not Thread-safe
Using a instance attribute allows more threads to each have a separate instance with it's own config.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top