Question by someone coming from C...

S

Skye

Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off. If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc

So I guess my questions are:

1. there doesn't seem to be a way to define global constants like in
other languages?
2. any special voodoo to use bitfields in Python?

Thanks!
Skye
 
L

Lie

Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off.  If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc

So I guess my questions are:

1. there doesn't seem to be a way to define global constants like in
other languages?

Global variables is like this:

-- module.py --
someglobal = 1
def func():
print someglobal
# This makes someglobal readonly,
# any attempt to write to someglobal
# would create a new local variable.

def func2():
global someglobal
someglobal = 2
# this allows you to manipulate the global
# variable
-- --
2. any  special voodoo to use bitfields in Python?

That's a not a good idea in Python. In C, it might worth saving some
few bytes of memory especially for embedded application, in python
it's just not worth it, the virtual machine is way huge compared to
the few bytes of space saved.

OK, it is possible to do bitfield manipulation in python:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/113799 but
it's not really worth it
 
S

Skye

OK, sounds good. So if not bitfields, what would be a good Python-y
way to do it?
Flip booleans in a "debug config" dictionary or something?

Skye
 
M

Matimus

Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off. If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc

So I guess my questions are:

1. there doesn't seem to be a way to define global constants like in
other languages?
2. any special voodoo to use bitfields in Python?

Thanks!
Skye

There is no conventional way to define a constant. There may be some
tricks if you look around, but I've been coding Python for a long time
and never actually needed one. The side effect is that you could
redefine one of the values at run-time. By naming convention though,
the user will know not to do that, just like they know not to mess
with attributes of an object that begin with "_". If they do mess with
it, well, they better know what they are doing.

There is no special bitfield voodoo that I know of.

Generally, naming conventions are the same as they would be in C (all
caps):

FOO = 0x01
BAR = 0x02
BAZ = 0x04

val = FOO | BAR | BAZ

if val & BAR:
#do bar stuff

The only time to do that sort of thing (in python) is when interacting
with something else that isn't written in Python though. In general,
for logging, just use the standard logging module:
http://docs.python.org/lib/module-logging.html


Matt
 
L

Lie

OK, sounds good.  So if not bitfields, what would be a good Python-y
way to do it?

The word is "pythonic".
Flip booleans in a "debug config" dictionary or something?

I'm not really sure, I've been programming with Python (and some other
languages) but never really felt the need to store data in such super-
efficient manners. I reckon a dict should do the job and it would be
easier to read too compared to bitfield, since dict's entry is named.

Actually, in python I usually do not put debugging codes before
entering debugging cycle, and I usually remove all those debugging
codes when the debugging cycle has finished (I'm talking for myself,
not the whole python community).
 
D

Diez B. Roggisch

Skye said:
Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off. If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc


For debugging - use the module logging. And configure properly.

Diez
 
J

John Krukoff

Thanks! It looks like subclassing the logging module would be a much
better idea :)

Skye

Really, the logging module is heavy weight enough, it's very doubtful
you need to add any functionality at all.

If you look at the documentation for logger objects, you'll see that you
can use a number of them, and set different logging levels for each one.
So, to get equivalent functionality to your bitfields, instead make a
separate logger for each category (config, options, blah...) and call
the object to log for that type.

i.e. config.debug( ... ), options.error( ... )

Since you probably want access to these from many different places in
your code, I find the simplest way is to create a logging module of your
own (not called logging, obviously) and instantiate all of your loggers
in that namespace, then import that one module as needed.

Perhpas you want one logging message to qualify as several different
types? That's the only place where I could see this being too verbose,
but even then it'd be easy to make a wrapper function that made that
easy given a collection of loggers.
 
C

Carl Banks

Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off. If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc

So I guess my questions are:

1. there doesn't seem to be a way to define global constants like in
other languages?
2. any special voodoo to use bitfields in Python?

Apart from the good advice "use the logging module", here is the
Pythonic way you'd do this sort of thing in general. (There's not
always a spiffy built-in module for anything you want to do; just
usually. :)

The lack of globals is a minor issue; you can get globally accessible
values by storing them in a module and importing that module.

The way I'd do the above is to define a module, say config.py, to hold
configuration options. Then I'd define each condition in its own
variable:

debug_general = False
debug_config = False
debug_options = False

I could then enable debugging by changing the value:

import config
config.debug_general = True

And I could use print debugging output based on the config settings
like this:

import config
if config.debug_general or config.debug_options:
print_debugging_info()

But again, the logging modules handles all this for you so no point
for this particular task.

P.S. I'd do it more or less this way in C, too.


Carl Banks
 
S

Skye

Very cool - I'm liking the pythonic way of doing things more and
more.
The logger namespace/singleton idea makes great sense!

I see how the module variables make globals irrelevant, thanks!

Skye
 
B

Bruno Desthuilliers

Skye a écrit :
Writing this app in Python, not sure what the "best practice" would
be.

I want a bitfield global logging level that allows me to turn specific
debugging modules on and off. If I was doing this in C, I'd just use
some globals like:

unsigned int debug_level = 0;
#define DEBUG_GENERAL 0x0001
#define DEBUG_CONFIG 0x0002
#define DEBUG_OPTIONS 0x0004
etc etc

So I guess my questions are:

1. there doesn't seem to be a way to define global constants like in
other languages?
2. any special voodoo to use bitfields in Python?

Others already gave you the best advises (namely: using the logging
module). But let's answer your questions anyway:

1/ by convention, anything named ALL_UPPER is considered a constant.
Anyone breaking your code by messing with a PSEUDO_CONSTANT is on it's
own and has no right to complain. Consider it as a "warranty void if
unsealed" warning.


2/ just use plain integers and bitwise operators. But we're usually more
concerned about readability than about saving bits, and I've rarely
(maybe twice ?) seen bitfields used that way in Python.
 
C

Christian Heimes

John said:
Since you probably want access to these from many different places in
your code, I find the simplest way is to create a logging module of your
own (not called logging, obviously) and instantiate all of your loggers
in that namespace, then import that one module as needed.

No, don't do that. Simple do

import logging
log = logging.getLogger("some_name")

The logging module takes care of the rest. The logging.getLogger()
function creates a new logger *only* when the name hasn't been used yet.

Christian
 
J

John Krukoff

No, don't do that. Simple do

import logging
log = logging.getLogger("some_name")

The logging module takes care of the rest. The logging.getLogger()
function creates a new logger *only* when the name hasn't been used yet.

Christian

Nifty, I never noticed that function, thanks for pointing it out as
it'll make my application a bit simpler.

Now, if they'd only add a syslog module that uses the libc syslog
interface (sure, it wouldn't be thread safe, but at least it'd be
portable to AIX, unlike the current one), I'll be a happy camper.
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top