Global variables within classes.

MarkE mark.english at rbccm.com
Fri Nov 30 06:54:52 EST 2007


> Kevac Marko <mke... at gmail.com> writes:
> > When changing default value, is there any way to change class
> > attribute and all referenced attributes too?
>
> > class M:
> >     name = u"Marko"
>
> > a, b = M(), M()
> > a.name = u"Kevac"
> > print M.name, a.name, b.name
> > -> Marko Kevac Marko
>
> > Is there any way to get here -> Kevac Kevac Kevac ?
> > Or what is the right way of keeping global variables in classes?
>
I suppose this works, but I agree with Hrvoje Niksic that you're
fighting the language, since by forcing such low level features to
behave differently you're going to end up confusing potentially
yourself, and definitely other Python programmers in the long term.

I've probably skipped lots of edge cases which will catch you out in
exciting, fun ways but other than that good luck...
import types
class Meta(type):
    def __new__(metacls, name, bases, dictionary):
        newClass = super(Meta, metacls).__new__(metacls, name, bases,
                                                dictionary)
        def getInstanceAttribute(self, key):
            typeSelf = type(self)
            if not key.startswith('__'): #If normal key
                try: #To get from class
                    return getattr(typeSelf, key)
                except AttributeError: #Not in class
                    #Get from instance
                    return super(typeSelf, self).__getattribute__(key)
            else: #Else special key
                #Get from instance
                return super(typeSelf, self).__getattribute__(key)
        newClass.__getattribute__ =
types.MethodType(getInstanceAttribute,
                                                     None,
                                                     newClass)
        def setInstanceAttribute(self, key, val):
            typeSelf = type(self)
            if not key.startswith('__'): #If normal key
                if hasattr(typeSelf, key): #If in class
                    return setattr(typeSelf, key, val)
                else: #Else not in class
                    #Set in instance
                    return super(typeSelf, self).__setattr__(key, val)
            else: #Else special key
                return super(typeSelf, self).__setattr__(key, val)
        newClass.__setattr__ = types.MethodType(setInstanceAttribute,
                                                None,
                                                newClass)
        return newClass

class M(object):
    __metaclass__ = Meta
    name = u"Marko"
a, b = M(), M()
a.name = u"Kevac"
print M.name, a.name, b.name



More information about the Python-list mailing list