作为下面的玩具示例,它们都创建了相同的类(尽管一个使用Foo.spam()
而另一个使用Foo.spam
来获取值)。我的问题是,选择一个而不是另一个的标准是什么?如果需要经常访问spam
,那么由于函数开销,最好使用第二类实现吗?还要别的吗?
class Foo(object):
def __init__(self, a):
self.a = "init"
@classmethod
def spam(cls, value=2):
return value + 1
Foo.spam() # -> 3
Foo.spam(3) #-> 4
class Foo(object):
spam = 3
def __init__(self, a):
self.a = "init"
Foo.spam #-> 3
Foo.spam = 4
Foo.spam #-> 4
答案 0 :(得分:3)
我不认为你想要完成的任何事情都是正确的(为类属性分配一个默认值)。你为什么不这样做呢?
class Foo(object):
def __init__(self, a = 'init'):
self.a = a
self.spam = 2
然后:
>>> a_foo = Foo()
>>> a_foo.spam
2
>>> a_foo.spam = 3
>>> a_foo.spam
3
如果通过静态类属性(第二个示例)执行此操作,则可以根据您分配/访问它的方式获得非常不同的行为:
class Foo(object):
spam = 2
def __init__(self, a = 'init'):
self.a = a
然后:
>>> a_foo1 = Foo()
>>> a_foo2 = Foo()
>>> a_foo1.spam
2
>>> a_foo2.spam
2
>>> Foo.spam = 3
>>> a_foo1.spam
3
>>> a_foo2.spam
3
# But now they'll diverge
>>> a_foo1.spam = 5
>>> a_foo1.spam
5
>>> a_foo2.spam
3
>>> Foo.spam = 2
>>> a_foo1.spam
5
>>> a_foo2.spam
2
如果您尝试将其设置为修改spam
的任何实例副本,则修改所有 实例' s spam
的副本,您使用的属性与静态属性相结合
class Foo(object):
_spam = 2
def __init__(self, a = 'init'):
self.a = a
@property
def spam(self):
return Foo._spam
@spam.setter
def spam(self, value)
Foo._spam = value
>>> a_foo1 = Foo()
>>> a_foo2 = Foo()
>>> a_foo1.spam
2
>>> a_foo2.spam
2
>>> a_foo1.spam = 3
>>> a_foo2.spam
3
虽然这种单例属性行为有点危险,并且可能被某些人视为反模式,因为类的大多数用户不希望修改一个实例的属性来修改所有实例'属性。你肯定需要有一个很好的理由这样做。
答案 1 :(得分:2)
如果方法没有做任何事情,只是返回属性值,只需使用属性。
但是,你的例子很奇怪,因为你传递了你想要的值。如果您只想要数字3,则无需使用Foo.spam(3)
或 Foo.spam = 3
;只需使用数字3。