tags:

views:

327

answers:

6

I have the following variables declared in a lot of functions, as I need those values in each one of them. Is there anyway I can declare them at a global scope or something, such as I won't have to declare them in all my methods? I am using all this methods on instance methods of a class of mine.

x = 0
y = 1
t = 2

In c# I'd just declare them as global class variables, but the problem is that I don't want to have to use them always as self.x, self.y and self.z, as it gets my algorithm's code uglier than it already is. How would you do this?

A typical usage of this would be:

def _GetStateFromAction(self, state, action):
    x = 0
    y = 1
    t = 2

    if (action == 0):
        return (state[x], state[y] - 1, state[t])

    if (action == 1):
        return (state[x] - 1, state[y], state[t])
+9  A: 

If they're all within a single module, then they only live in that module's namespace and you don't have to worry about name clashes. (And you can still import them into other namesapaces)

For example

MyModWithContstants.py

x = 0
y = 0

def someFunc():
  dosomethingwithconstants(x,y)

and we can also do

anotherMod.py

from MyModWithConstants import x
# and also we can do
import MyModWithConstants as MMWC

def somOtherFunc():
  dosomethingNew(x, MMWC.y)  
  ## x and MMWC.y both refer to things in the other file
Andrew Jaffe
Ah, didn't know I could do that.
devoured elysium
How about if you've got a large module and don't want a global to be quite that global? How would you achieve the same result just within the class?
KenFar
Just put the definition inside the class. They just become members of the class.
Andrew Jaffe
Right - but now you've got to qualify it with the class name which violates the objective of keeping the variable name concise. Is there a good way to work around that?
KenFar
I don't think you can avoid the "self." reference. But really, why would you want to? If you have two *different* things with the same name in a single module, isn't that asking for confusion?
Andrew Jaffe
No - I agree with you completely. However, lets take a case in which you've got a class within a large module. That class needs to share a constant between various methods. It's a non-changing class variable. I don't want to define it at the module level, and since it doesn't change with each instance - I don't want to define it at the instance level. And I'd prefer to avoid having the methods forced to qualify it with the class name every time they use it. Is that possible? Or is it a bad idea?
KenFar
Hmmm, perhaps you're trying to have your cake and eat it, too? Python *does* have a mechanism for this -- modules -- which you don't want to use. Just do a single class per module (which I believe is officially-recommended practice, although I guess it's not in the infamous PEP 8)
Andrew Jaffe
Huh, hadn't heard of one class per module as a guideline. I'll have to think about that more and look for more suggestions on this. Thanks for the tips!
KenFar
+1  A: 

You could simply declare these variables at the module level (i.e. the top level of the .py source file) and there will be no need to use self or anything like that. In that case I think the convention would be to give them uppercase names.

By the way, I can't help but point out that you could be declaring them like this:

x, y, t = 0, 1, 2
Ben James
we can argue about the readability, but python tuple assignment support sure is cool. :D
CrazyJugglerDrummer
A: 

Have you considered

global x, y, z
x=0
y=1
z=2

?

inspectorG4dget
I don't think global means what you think it means
gnibbler
I think you're right... I was quite confused with the question... I don't see any edits/clarifications. Please clarify the question further if you would still like me to post an answer
inspectorG4dget
+1  A: 

If these "variables" are truly constants declaring them at module level seems logical. If you have to modify them from inside a function you just have to declare them global in that function.

kriss
A: 
import __builtin__
__builtin__.__dict__["X"] = 5

This will store the X constant in all modules executed until the interpreter exits.

Remember though to use it with care, as other python developers are not likely to expect this. I use it mainly for storing the translation function '_'.

Thomas Ahle
Sorry, but this seems like a pretty bad idea to me. Bad enough that I would probably flat out refuse to use it, and look for a better solution (luckily, many exist in this case).
Edan Maor
+5  A: 

In addition to the separate module trick, if I want them in the same module I'll often put them in a class, like this:

class PathConstants(object):
    CSIDL_DESKTOP = 0
    CSIDL_PROGRAMS = 2

def get_desktop():
    return _get_path_buf(PathConstants.CSIDL_DESKTOP)

If you want to make them more constant-y, then you can make setattr throw:

class ConstantExeption(Exception):
    pass

class ProgramConstants(object):
    foo = 10
    bar = 13
    def __setattr__(self, key, val):
        raise ConstantExeption("Cannot change value of %s" % key)

# got to use an instance...
constants = ProgramConstants()
print constants.foo
constants.bar = "spam"

The traceback:

10
Traceback (most recent call last):
  File "...", line 14, in <module>
    constants.bar = "spam"
  File "...", line 9, in __setattr__
    raise ConstantExeption("Cannot change value of %s" % key)
__main__.ConstantExeption: Cannot change value of bar
Ryan Ginstrom