【问题标题】:Is there a way to modify a class in a class method in Python?有没有办法在 Python 的类方法中修改一个类?
【发布时间】:2009-08-03 13:18:05
【问题描述】:

我想在 Python 的类方法中对类执行 setattr 之类的操作,但该类不存在,所以我基本上得到:

NameError: global name 'ClassName' is not defined

类方法有没有办法修改类?像这样但实际上有效的东西:

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

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

【问题讨论】:

  • 请发布一个小而完整的示例,说明您正在尝试做什么。

标签: python


【解决方案1】:

类方法获取作为第一个参数传递的类:

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在第二步之后的命名空间中,所以在第三步变成了类属性。

【讨论】:

  • 有没有办法在Bla的体内跑cm?
  • 未达到预期结果(Bla 尚不存在)。但是如果你只是想在创建类时设置类属性storedValue,那么在正文中只说storedValue = "Hello" 有什么问题呢?
  • 那只是班级的一员。我正在尝试简化创建属性的丑陋而冗长的过程。
  • 那你真的要多解释了。您的代码示例将最重要的部分替换为“...”,这使得您很难理解您在尝试什么。
  • balpha,我认为它没有将最重要的部分放在...中。我已经删除了那些以防万一。示例代码仍然没有运行。开始运行类似的东西会非常有帮助。问题:评估 def HocusPocus 时 ClassName 不存在。
【解决方案2】:

您可以这样做的另一种方法是使用class decorator,尽管这些仅适用于 Python 2.6 及更高版本的 IIRC。

类似这样的:

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

@addattributes
class MyClass(object):
    pass

print MyClass.foobar

当你想用一些特定的功能/属性“装饰”一些类时,这种方法最有用。在您的情况下,如果您只想这样做一次,您可能只想使用前面显示的类方法。

【讨论】:

    【解决方案3】:

    虽然已经提出了许多好的建议,但最接近最初请求的代码的建议是:

    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
    

    【讨论】:

    • 问题是你需要重复自己:blah 和 "blah"。
    • 另一个问题是我没有看到写fget和fset的方法来获取和设置对象中的属性名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 2019-11-30
    相关资源
    最近更新 更多