osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Can global variable be passed into Python function?


On Fri, Feb 28, 2014 at 9:02 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Yes, enums are long overdue. However, since any distinct objects will
> do, there is nothing preventing you from using string objects.
>

String literals will often be interned if they look like (especially,
if they *are*) identifiers, so if you want to prevent other strings
from happening to match, you can't trust 'is'.

>>> class Foo:
    INIT = "INIT"
    def __init__(self):
        self.state = self.INIT
    def initializing(self):
        return self.state is self.INIT
>>> a=Foo()
>>> a.initializing()
True
>>> a.state="INIT"
>>> a.initializing()
True


So you should use some string value that doesn't look like an identifier:

>>> class Foo:
    INIT = "<<INIT>>"
    def __init__(self):
        self.state = self.INIT
    def initializing(self):
        return self.state is self.INIT
>>> a=Foo()
>>> a.initializing()
True
>>> a.state="<<INIT>>"
>>> a.initializing()
False

But even then, chances are you can force the matter by interning explicitly.

>>> class Foo:
    INIT = ">>INIT<<"
    def __init__(self):
        self.state = self.INIT
    def initializing(self):
        return self.state is self.INIT
>>> a=Foo()
>>> a.initializing()
True
>>> sys.intern(a.state)
'>>INIT<<'
>>> a.state=sys.intern(">>INIT<<")
>>> a.initializing()
True

Note that in no case did I at all tamper with the class definition,
either to change its idea of the INIT string or to fetch that
particular object. Two equal strings, in Python, might and might not
be identical, and you simply cannot rely on interning either way.

The third example, incidentally, depends on sys.intern reusing a.state
as the "one interned string". This will normally be what happens if
it's the first string of that value to be used. So you might be able
to first force the strings to be in the interning table, and then
force your sentinels to be different objects. But at that point, you
really should be using object(), or a proper enum module.

If you're using strings as state values, you should be using == to
compare them. Nothing else is safe.

ChrisA