有没有办法在Python中的类方法中修改类?

问题描述:

我想做一些像SETATTR在类方法Python中的类,但该类不存在,所以我基本上得到:有没有办法在Python中的类方法中修改类?

NameError: global name 'ClassName' is not defined 

是否有一个类的方法来修改类的方法吗?这样但一些实际工作:

class ClassName(object): 
    def HocusPocus(name): 
     setattr(ClassName, name, name) 

    HocusPocus("blah") 
    HocusPocus("bleh") 
+1

请发布一个小的完整示例,显示您正在尝试执行的操作。 – 2009-08-03 13:19:28

类方法获得的第一个参数传递的类:

class Bla(object): 
    @classmethod 
    def cm(cls,value): 
     cls.storedValue = value 

Bla.cm("Hello") 

print Bla.storedValue # prints "Hello" 

编辑:我想我现在明白你的问题。如果我没有得到它,所有你想做的事是这样的:

class Bla(object): 
    storedValue = "Hello again" 

print Bla.storedValue # prints "Hello again" 

类创建在Python(非常)简单的说:

  1. 创建一个新的命名空间。
  2. 使用此命名空间运行在类体内部找到的代码
  3. 将名称空间中剩下的所有内容都放入类中作为类属性。

由于storedValue是在步骤2中后的命名空间,它变成了一个类属性在步骤3

+0

有没有办法在Bla身上运行cm? – Pablo 2009-08-03 14:34:07

+0

不符合预期结果(Bla尚不存在)。但是如果你只是想在类的创建中设置class属性storedValue,那么刚才在正文中说storedValue =“Hello”有什么问题呢? – balpha 2009-08-03 14:46:52

另一种方法可以做到这一点是使用一个class decorator,但这些仅仅是可用从Python 2.6开始IIRC。

事情是这样的:

def addattributes(cls): 
    cls.foobar = 10 
    return cls 

@addattributes 
class MyClass(object): 
    pass 

print MyClass.foobar 

这种这种最有用的,当你想“装修”中的一些类与一些特定的功能/性能。在你的情况下,如果你只想做一次,你可能只想使用前面所示的类方法。

虽然很多很好的建议已经提出,最接近的一种,可以得到最初请求的代码,那就是:

class ClassName(object): 
    def HocusPocus(name): 
     setattr(ClassName, name, property(fget=..., fset=...)) 

    HocusPocus("blah") 
    HocusPocus("bleh") 

是这样的:

class ClassName(object): 

    def HocusPocus(name): 
     return property(fget=..., fset=...) 

    blah = HocusPocus("blah") 
    bleh = HocusPocus("bleh") 

我假设神秘...编辑部分也需要访问name(否则不需要将它作为参数传递)。

问题是,在类体中,HocusPocus仍然只是一个函数(因为类对象在类体完成执行之前还不存在,所以它本质上就像一个函数体,它在本地运行dict [没有通常由Python编译器对真实函数的本地语言执行的名称空间优化,但这只会使语义更简单!]),特别是它可以在该体内调用,可以返回一个值,可以指定该值(到类体的局部变量,它将在主体执行结束时变成类属性)等等。

如果你不想ClassName.HocusPocus挂在后面,当你完成的类体中执行它只需添加一个del声明(例如在类体的最后一条语句):

del HocusPocus