English 中文(简体)
class __init__ (not instance __init__)
原标题:

Here s a very simple example of what I m trying to get around:

class Test(object):
    some_dict = {Test: True}

The problem is that I cannot refer to Test while it s still being defined

Normally, I d just do this:

class Test(object):
    some_dict = {}
    def __init__(self):
        if self.__class__.some_dict == {}:
            self.__class__.some_dict = {Test: True}

But I never create an instance of this class. It s really just a container to hold a group of related functions and data (I have several of these classes, and I pass around references to them, so it is necessary for Test to be it s own class)

So my question is, how could I refer to Test while it s being defined, or is there something similar to __init__ that get s called as soon as the class is defined? If possible, I want self.some_dict = {Test: True} to remain inside the class definition. This is the only way I know how to do this so far:

class Test(object):
    @classmethod
    def class_init(cls):
        cls.some_dict = {Test: True}
Test.class_init()
最佳回答

The class does in fact not exist while it is being defined. The way the class statement works is that the body of the statement is executed, as a block of code, in a separate namespace. At the end of the execution, that namespace is passed to the metaclass (such as type) and the metaclass creates the class using the namespace as the attributespace.

From your description, it does not sound necessary for Test to be a class. It sounds like it should be a module instead. some_dict is a global -- even if it s a class attribute, there s only one such attribute in your program, so it s not any better than having a global -- and any classmethods you have in the class can just be functions.

If you really want it to be a class, you have three options: set the dict after defining the class:

class Test:
    some_dict = {}
Test.some_dict[Test] = True

Use a class decorator (in Python 2.6 or later):

def set_some_dict(cls):
    cls.some_dict[cls] = True

@set_some_dict
class Test:
    some_dict = {}

Or use a metaclass:

class SomeDictSetterType(type):
    def __init__(self, name, bases, attrs):
        self.some_dict[self] = True
        super(SomeDictSetterType, self).__init__(name, bases, attrs)

class Test(object):
    __metaclass__ = SomeDictSetterType
    some_dict = {}
问题回答

You could add the some_dict attribute after the main class definition.

class Test(object):
  pass
Test.some_dict = {Test: True}

I ve tried to use classes in this way in the past, and it gets ugly pretty quickly (for example, all the methods will need to be class methods or static methods, and you will probably realise eventually that you want to define certain special methods, for which you will have to start using metaclasses). It could make things a lot easier if you just use class instances instead - there aren t really any downsides.

A (weird-looking) alternative to what others have suggested: you could use __new__:

class Test(object):
    def __new__(cls):
        cls.some_dict = {cls: True}

Test()

You could even have __new__ return a reference to the class and use a decorator to call it:

def instantiate(cls):
    return cls()

@instantiate
class Test(object):
    def __new__(cls):
        cls.some_dict = {cls: True}
        return cls

You can also use a metaclass (a function here but there are other ways):

def Meta(name, bases, ns):
    klass = type(name, bases, ns)
    setattr(klass,  some_dict , { klass: True })
    return klass

class Test(object):
    __metaclass__ = Meta

print Test.some_dict

Thomas s first example is very good, but here s a more Pythonic way of doing the same thing.

class Test:
    x = {}
    @classmethod
    def init(cls):
        # do whatever setup you need here
        cls.x[cls] = True
Test.init()




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签