1

Pep8建议始终cls用作类方法定义的第一个参数。现在假设我想使用一个类变量(在这种情况下:)cls.cartridge_state,它也可以在实例方法中使用(在这种情况下:)__init__。所以为此我需要使变量成为全局变量(参见下面的代码)。但是实例化FountainPen会产生以下运行时错误:

self.cartridge_state = cls.cartridge_state
NameError: global name 'cls' is not defined

但是当我更改global cartridge_stateglobal cls.cartridge_state我尝试导入模块时再次收到 syntaxError 。

class FountainPen(object):
    cartridge_ink = "water-based"
    @classmethod
    def toggle_default_cartridge_state(cls):
        i = 0
        cartridge_states = ['non-empty','empty']
        global cartridge_state
        cls.cartridge_state = cartridge_states[i]
        i += 1

    def __init__(self):
        self.cartridge_state = cls.cartridge_state
        global number_of_refills
        self.number_of_refills = 0

    def write(self):
        print Pen.write(self)
        self.cartridge_state = "empty"
        return self.cartridge_state

    def refill(self):
        self.cartridge_state = "non-empty"
        self.number_of_refills += 1

如何让类变量cartridge_state符合 pep8 并使此代码正常工作?

4

3 回答 3

5

可以通过以下方式读取类属性self

class FountainPen(object):
    cartridge_ink = "water-based"
    default_cartridge_state = "empty"

    @classmethod
    def toggle_default_cartridge_state(cls):
        if cls.default_cartridge_state == "empty":
            cls.default_cartridge_state = "non-empty"  
        else:
            cls.default_cartridge_state = "empty"

    def __init__(self):
        self.cartridge_state = self.default_cartridge_state

    def write(self):
        print Pen.write(self)
        self.cartridge_state = "empty"
        return self.cartridge_state

    def refill(self):
        self.cartridge_state = "non-empty"
        self.number_of_refills += 1
于 2012-06-19T13:33:02.737 回答
1

PEP 8说的是这应该cls是第一个论点。self在实例方法中定义第一个参数时的方式相同。我想这是为了避免在调用这样的类方法时出现麻烦self.yourclassmethod()。但我不明白为什么需要@classmethod装饰器。

编辑:

我做的不同,而不是@classmethod我使用@staticmethod,但我意识到我们不是在谈论同一件事。如果有人认为我错了,请告诉我。

例子:

class Bar(object):
    @staticmethod
    def foo(myarg):
        return myarg * 2

Bar.foo(2)

编辑2:

我纠正自己,@classmethod@staticmethod代表不同的东西(见这里)。静态方法不应该修改类中的变量。

于 2012-06-19T13:24:04.813 回答
0

忘了global; global与类和对象无关。

当您访问对象的属性时,将首先在对象上查找,然后在类上查找。这意味着如果您希望一个对象拥有自己的属性副本并且不反映对该属性的后续更新,那么您需要做的就是将其复制到__init__

def __init__(self):
    self.prop = self.prop
于 2012-06-19T13:47:19.733 回答