321

I have a class with two class methods (using the classmethod() function) for getting and setting what is essentially a static variable. I tried to use the property() function with these, but it results in an error. I was able to reproduce the error with the following in the interpreter:

class Foo(object):
 _var = 5
 @classmethod
 def getvar(cls):
 return cls._var
 @classmethod
 def setvar(cls, value):
 cls._var = value
 var = property(getvar, setvar)

I can demonstrate the class methods, but they don't work as properties:

>>> f = Foo()
>>> f.getvar()
5
>>> f.setvar(4)
>>> f.getvar()
4
>>> f.var
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
TypeError: 'classmethod' object is not callable
>>> f.var=5
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
TypeError: 'classmethod' object is not callable

Is it possible to use the property() function with @classmethod decorated functions?

martineau
124k29 gold badges180 silver badges318 bronze badges
asked Sep 24, 2008 at 17:37
0

19 Answers 19

201

3.8 < Python < 3.11

Can use both decorators together. See this answer.

Python 2 and python 3 (works in 3.9-3.10 too)

A property is created on a class but affects an instance. So if you want a classmethod property, create the property on the metaclass.

>>> class foo(object):
... _var = 5
... class __metaclass__(type): # Python 2 syntax for metaclasses
... pass
... @classmethod
... def getvar(cls):
... return cls._var
... @classmethod
... def setvar(cls, value):
... cls._var = value
... 
>>> foo.__metaclass__.var = property(foo.getvar.im_func, foo.setvar.im_func)
>>> foo.var
5
>>> foo.var = 3
>>> foo.var
3

But since you're using a metaclass anyway, it will read better if you just move the classmethods in there.

>>> class foo(object):
... _var = 5
... class __metaclass__(type): # Python 2 syntax for metaclasses
... @property
... def var(cls):
... return cls._var
... @var.setter
... def var(cls, value):
... cls._var = value
... 
>>> foo.var
5
>>> foo.var = 3
>>> foo.var
3

or, using Python 3's metaclass=... syntax, and the metaclass defined outside of the foo class body, and the metaclass responsible for setting the initial value of _var:

>>> class foo_meta(type):
... def __init__(cls, *args, **kwargs):
... cls._var = 5
... @property
... def var(cls):
... return cls._var
... @var.setter
... def var(cls, value):
... cls._var = value
...
>>> class foo(metaclass=foo_meta):
... pass
...
>>> foo.var
5
>>> foo.var = 3
>>> foo.var
3
STerliakov
8,8583 gold badges25 silver badges59 bronze badges
answered Nov 26, 2009 at 0:58

12 Comments

This doesn't seem to work for me in Python 3.2. If I change foo.__metaclass__.var = property(foo.getvar.im_func, foo.setvar.im_func) to foo.__metaclass__.var = property(foo.getvar.__func__, foo.setvar.__func__) I get "AttributeError: type object 'foo' has no attribute 'var'" when executing "foo.var".
I am not quite sure to understand, what would be the Python 3.x way to write this then ?
@Josay: You'd need to define the metaclass first, then define the class using the new class Foo(metaclass=...) syntax.
It's worth noting that these properties won't be available on instances of your class (foo in this case), just on the class itself -- by virtue of how metaclasses work.
@Devyzr It happens because... well, actually, it's right in the name, though it's a non-obvious consequence. A class Foo's metaclass Meta is the class of the class Foo, and Foo itself will therefore be an instance of Meta — but instances of Foo will NOT be instances of Meta. (They're instances of Foo, and Foo does not inherit from Meta, it instantiates Meta.) So, any properties Foo gains by virtue of being an instance of Meta are not passed along to its instances. If they were, Meta would be a parent class of Foo, not a meta class for Foo.
|
170

Update: The ability to chain @classmethod and @property was removed in Python 3.13 😕.

In Python 3.9 You could use them together, but (as noted in @xgt's comment) it was deprecated in Python 3.11, so it is not longer supported (but it may work for a while or reintroduced at some point).

Check the version remarks here:

https://docs.python.org/3.11/library/functions.html#classmethod

However, it used to work like so:

class G:
 @classmethod
 @property
 def __doc__(cls):
 return f'A doc for {cls.__name__!r}'

Order matters - due to how the descriptors interact, @classmethod has to be on top.

answered Nov 8, 2020 at 13:53

25 Comments

@Pycz just stack @classmethod @property @functools.cache to get the same behavior
What about the setter?
classproperty chain was removed with Python 3.11. You cannot use @classproperty together with @property any longer: docs.python.org/3.11/library/…
@xqt WHHHYyyy!? The documentation says nothing about the rationale! People wrote code relying on stuff like this! What are they doing!? What's the justification? Any links to mailing list or bug tracker discussions or PEP where this was decided?
Looks like at least some of the rationale is here.
|
121

I hope this dead-simple read-only @classproperty decorator would help somebody looking for classproperties.

class classproperty(property):
 def __get__(self, owner_self, owner_cls):
 return self.fget(owner_cls)
class C(object):
 @classproperty
 def x(cls):
 return 1
assert C.x == 1
assert C().x == 1
answered Nov 29, 2012 at 11:32

10 Comments

Does this work with subclasses? (can a subclass override classproperties?)
Umm yes? class D(C): x = 2; assert D.x == 2
Easily fixed: add a __set__ that raises an ValueError to prevent override.
... AttributeError, and that only works to block C().x = val, not C.x = val
Thanks for this awesome snippet! I've created a pip installable package with this and a cached_classproperty here: github.com/hottwaj/classproperties
|
76

Reading the Python 2.2 release notes, I find the following.

The get method [of a property] won't be called when the property is accessed as a class attribute (C.x) instead of as an instance attribute (C().x). If you want to override the __get__ operation for properties when used as a class attribute, you can subclass property - it is a new-style type itself - to extend its __get__ method, or you can define a descriptor type from scratch by creating a new-style class that defines __get__, __set__ and __delete__ methods.

NOTE: The below method doesn't actually work for setters, only getters.

Therefore, I believe the prescribed solution is to create a ClassProperty as a subclass of property.

class ClassProperty(property):
 def __get__(self, cls, owner):
 return self.fget.__get__(None, owner)()
class foo(object):
 _var=5
 def getvar(cls):
 return cls._var
 getvar=classmethod(getvar)
 def setvar(cls,value):
 cls._var=value
 setvar=classmethod(setvar)
 var=ClassProperty(getvar,setvar)
assert foo.getvar() == 5
foo.setvar(4)
assert foo.getvar() == 4
assert foo.var == 4
foo.var = 3
assert foo.var == 3

However, the setters don't actually work:

foo.var = 4
assert foo.var == foo._var # raises AssertionError

foo._var is unchanged, you've simply overwritten the property with a new value.

You can also use ClassProperty as a decorator:

class foo(object):
 _var = 5
 @ClassProperty
 @classmethod
 def var(cls):
 return cls._var
 @var.setter
 @classmethod
 def var(cls, value):
 cls._var = value
assert foo.var == 5
answered Sep 5, 2009 at 14:12

5 Comments

I don't think the setter part of the ClassProperty actually works as described: while the example's assertions all pass, at the end foo._var == 4 (not 3, as implied). Setting the property clobbers the property itself. When class-properties were discussed on python-dev it was pointed out that, while getters are trivial, setters are difficult (impossible?) without a metaclass
@Gabriel Totally correct. I can't believe no one pointed that out for two years.
I'm also not sure why you don't not just use self.fget(owner) and remove the need to have to use a @classmethod at all here? (that's what classmethod does, translate .__get__(instance, owner)(*args, **kwargs) to function(owner, *args, **kwargs) calls, via an intermediary; properties don't need the intermediary).
Your demonstration is lacking any actual transformation in either the getter or the setter that would neatly demonstrate that your foo.var = 3 assignment doesn't actually go through the property, and instead has simply replaced the property object on foo with an integer. If you added assert isinstance(foo.__dict__['var'], ClassProperty) calls between your assertions you'd see that fail after foo.var = 3 is executed.
Python classes don't support descriptor binding on setting on the class itself, only on getting (so instance.attr, instance.attr = value and del instance.attr will all bind the descriptor found on type(instance), but while classobj.attr binds, classobj.attr = value and del classobj.attr do not and instead replace or delete the descriptor object itself). You need a metaclass to support setting and deleting (making the class object the instance, and the metaclass the type).
49

Is it possible to use the property() function with classmethod decorated functions?

No.

However, a classmethod is simply a bound method (a partial function) on a class accessible from instances of that class.

Since the instance is a function of the class and you can derive the class from the instance, you can can get whatever desired behavior you might want from a class-property with property:

class Example(object):
 _class_property = None
 @property
 def class_property(self):
 return self._class_property
 @class_property.setter
 def class_property(self, value):
 type(self)._class_property = value
 @class_property.deleter
 def class_property(self):
 del type(self)._class_property

This code can be used to test - it should pass without raising any errors:

ex1 = Example()
ex2 = Example()
ex1.class_property = None
ex2.class_property = 'Example'
assert ex1.class_property is ex2.class_property
del ex2.class_property
assert not hasattr(ex1, 'class_property')

And note that we didn't need metaclasses at all - and you don't directly access a metaclass through its classes' instances anyways.

writing a @classproperty decorator

You can actually create a classproperty decorator in just a few lines of code by subclassing property (it's implemented in C, but you can see equivalent Python here):

class classproperty(property):
 def __get__(self, obj, objtype=None):
 return super(classproperty, self).__get__(objtype)
 def __set__(self, obj, value):
 super(classproperty, self).__set__(type(obj), value)
 def __delete__(self, obj):
 super(classproperty, self).__delete__(type(obj))

Then treat the decorator as if it were a classmethod combined with property:

class Foo(object):
 _bar = 5
 @classproperty
 def bar(cls):
 """this is the bar attribute - each subclass of Foo gets its own.
 Lookups should follow the method resolution order.
 """
 return cls._bar
 @bar.setter
 def bar(cls, value):
 cls._bar = value
 @bar.deleter
 def bar(cls):
 del cls._bar

And this code should work without errors:

def main():
 f = Foo()
 print(f.bar)
 f.bar = 4
 print(f.bar)
 del f.bar
 try:
 f.bar
 except AttributeError:
 pass
 else:
 raise RuntimeError('f.bar must have worked - inconceivable!')
 help(f) # includes the Foo.bar help.
 f.bar = 5
 class Bar(Foo):
 "a subclass of Foo, nothing more"
 help(Bar) # includes the Foo.bar help!
 b = Bar()
 b.bar = 'baz'
 print(b.bar) # prints baz
 del b.bar
 print(b.bar) # prints 5 - looked up from Foo!
 
if __name__ == '__main__':
 main()

But I'm not sure how well-advised this would be. An old mailing list article suggests it shouldn't work.

Getting the property to work on the class:

The downside of the above is that the "class property" isn't accessible from the class, because it would simply overwrite the data descriptor from the class __dict__.

However, we can override this with a property defined in the metaclass __dict__. For example:

class MetaWithFooClassProperty(type):
 @property
 def foo(cls):
 """The foo property is a function of the class -
 in this case, the trivial case of the identity function.
 """
 return cls

And then a class instance of the metaclass could have a property that accesses the class's property using the principle already demonstrated in the prior sections:

class FooClassProperty(metaclass=MetaWithFooClassProperty):
 @property
 def foo(self):
 """access the class's property"""
 return type(self).foo

And now we see both the instance

>>> FooClassProperty().foo
<class '__main__.FooClassProperty'>

and the class

>>> FooClassProperty.foo
<class '__main__.FooClassProperty'>

have access to the class property.

answered Sep 17, 2016 at 4:21

Comments

38

Luckily, it's easy with the metaclass kwarg:

class FooProperties(type):
 @property
 def var(cls):
 return cls._var
class Foo(object, metaclass=FooProperties):
 _var = 'FOO!'

Then,

>>> Foo.var
'FOO!'

This works in any version of Python 3, see @Amit Portnoy's answer for an even cleaner method in Python 3.9 or newer.

mkrieger1
24.1k7 gold badges67 silver badges83 bronze badges
answered Nov 16, 2017 at 16:07

6 Comments

that is to say there is no simple way out of the box
@mehmet Is this not simple? Foo is an instance of its metaclass, and @property can be used for its methods just as it can for those of instances of Foo.
you had to define another class for a class, that is double the complexity assuming the metaclass is not reusable.
A classmethod works from both the class and the instance. This property only works from the class. I don't think this is what is being asked for.
@AaronHall If that's important, it's easily added in Foo.__new__. Though at that point it might be worth either using getattribute instead, or questioning if pretending a language feature exists is really the approach you want to take at all.
|
18

There is no reasonable way to make this "class property" system to work in Python.

Here is one unreasonable way to make it work. You can certainly make it more seamless with increasing amounts of metaclass magic.

class ClassProperty(object):
 def __init__(self, getter, setter):
 self.getter = getter
 self.setter = setter
 def __get__(self, cls, owner):
 return getattr(cls, self.getter)()
 def __set__(self, cls, value):
 getattr(cls, self.setter)(value)
class MetaFoo(type):
 var = ClassProperty('getvar', 'setvar')
class Foo(object):
 __metaclass__ = MetaFoo
 _var = 5
 @classmethod
 def getvar(cls):
 print "Getting var =", cls._var
 return cls._var
 @classmethod
 def setvar(cls, value):
 print "Setting var =", value
 cls._var = value
x = Foo.var
print "Foo.var = ", x
Foo.var = 42
x = Foo.var
print "Foo.var = ", x

The knot of the issue is that properties are what Python calls "descriptors". There is no short and easy way to explain how this sort of metaprogramming works, so I must point you to the descriptor howto.

You only ever need to understand this sort of things if you are implementing a fairly advanced framework. Like a transparent object persistence or RPC system, or a kind of domain-specific language.

However, in a comment to a previous answer, you say that you

need to modify an attribute that in such a way that is seen by all instances of a class, and in the scope from which these class methods are called does not have references to all instances of the class.

It seems to me, what you really want is an Observer design pattern.

answered Sep 24, 2008 at 20:38

4 Comments

I like the idea of the code example, but it seems like it would be a little clunky in practice.
What I'm trying to accomplish is pretty straight forward setting and getting of a single attribute that's used as a flag to modify the behavior of all instances so I think Observer would be overblown for what I'm trying to do. If there were multiple attributes in question then I'd be more inclined.
It seems that just making the functions public and calling them directly was the simplist solution. I was curious if I was doing something wrong or if I was trying to do was impossible. Sorry about the multiple comments by the way. 300 character limit sucks.
The nifty thing about the code example is that you can implement all the clunky bits once and then inherit them. Just move the _var into the derived class. class D1(Foo): _var = 21 class D2(Foo) _var = "Hello" D1.var 21 D2.var Hello
7

Setting it only on the meta class doesn't help if you want to access the class property via an instantiated object, in this case you need to install a normal property on the object as well (which dispatches to the class property). I think the following is a bit more clear:

#!/usr/bin/python
class classproperty(property):
 def __get__(self, obj, type_):
 return self.fget.__get__(None, type_)()
 def __set__(self, obj, value):
 cls = type(obj)
 return self.fset.__get__(None, cls)(value)
class A (object):
 _foo = 1
 @classproperty
 @classmethod
 def foo(cls):
 return cls._foo
 @foo.setter
 @classmethod
 def foo(cls, value):
 cls.foo = value
a = A()
print a.foo
b = A()
print b.foo
b.foo = 5
print a.foo
A.foo = 10
print b.foo
print A.foo
answered Mar 30, 2010 at 10:07

Comments

4

Half a solution, __set__ on the class does not work, still. The solution is a custom property class implementing both a property and a staticmethod

class ClassProperty(object):
 def __init__(self, fget, fset):
 self.fget = fget
 self.fset = fset
 def __get__(self, instance, owner):
 return self.fget()
 def __set__(self, instance, value):
 self.fset(value)
class Foo(object):
 _bar = 1
 def get_bar():
 print 'getting'
 return Foo._bar
 def set_bar(value):
 print 'setting'
 Foo._bar = value
 bar = ClassProperty(get_bar, set_bar)
f = Foo()
#__get__ works
f.bar
Foo.bar
f.bar = 2
Foo.bar = 3 #__set__ does not
answered Sep 24, 2008 at 18:08

Comments

3

Because I need to modify an attribute that in such a way that is seen by all instances of a class, and in the scope from which these class methods are called does not have references to all instances of the class.

Do you have access to at least one instance of the class? I can think of a way to do it then:

class MyClass (object):
 __var = None
 def _set_var (self, value):
 type (self).__var = value
 def _get_var (self):
 return self.__var
 var = property (_get_var, _set_var)
a = MyClass ()
b = MyClass ()
a.var = "foo"
print b.var
answered Sep 24, 2008 at 20:47

Comments

3

Give this a try, it gets the job done without having to change/add a lot of existing code.

>>> class foo(object):
... _var = 5
... def getvar(cls):
... return cls._var
... getvar = classmethod(getvar)
... def setvar(cls, value):
... cls._var = value
... setvar = classmethod(setvar)
... var = property(lambda self: self.getvar(), lambda self, val: self.setvar(val))
...
>>> f = foo()
>>> f.var
5
>>> f.var = 3
>>> f.var
3

The property function needs two callable arguments. give them lambda wrappers (which it passes the instance as its first argument) and all is well.

answered Sep 24, 2008 at 21:28

1 Comment

As Florian Bösch points out, the syntax required (by third-party libraries or legacy code) is foo.var.
3

For a functional approach pre Python 3.9 you can use this:

def classproperty(fget):
 return type(
 'classproperty',
 (),
 {'__get__': lambda self, _, cls: fget(cls), '__module__': None}
 )()
 
class Item:
 a = 47
 @classproperty
 def x(cls):
 return cls.a
Item.x
answered Dec 10, 2021 at 23:35

Comments

2

Here's a solution which should work for both access via the class and access via an instance which uses a metaclass.

In [1]: class ClassPropertyMeta(type):
 ...: @property
 ...: def prop(cls):
 ...: return cls._prop
 ...: def __new__(cls, name, parents, dct):
 ...: # This makes overriding __getattr__ and __setattr__ in the class impossible, but should be fixable
 ...: dct['__getattr__'] = classmethod(lambda cls, attr: getattr(cls, attr))
 ...: dct['__setattr__'] = classmethod(lambda cls, attr, val: setattr(cls, attr, val))
 ...: return super(ClassPropertyMeta, cls).__new__(cls, name, parents, dct)
 ...:
In [2]: class ClassProperty(object):
 ...: __metaclass__ = ClassPropertyMeta
 ...: _prop = 42
 ...: def __getattr__(self, attr):
 ...: raise Exception('Never gets called')
 ...:
In [3]: ClassProperty.prop
Out[3]: 42
In [4]: ClassProperty.prop = 1
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-4-e2e8b423818a> in <module>()
----> 1 ClassProperty.prop = 1
AttributeError: can't set attribute
In [5]: cp = ClassProperty()
In [6]: cp.prop
Out[6]: 42
In [7]: cp.prop = 1
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-e8284a3ee950> in <module>()
----> 1 cp.prop = 1
<ipython-input-1-16b7c320d521> in <lambda>(cls, attr, val)
 6 # This makes overriding __getattr__ and __setattr__ in the class impossible, but should be fixable
 7 dct['__getattr__'] = classmethod(lambda cls, attr: getattr(cls, attr))
----> 8 dct['__setattr__'] = classmethod(lambda cls, attr, val: setattr(cls, attr, val))
 9 return super(ClassPropertyMeta, cls).__new__(cls, name, parents, dct)
AttributeError: can't set attribute

This also works with a setter defined in the metaclass.

answered Jun 28, 2017 at 20:28

Comments

2

I found one clean solution to this problem. It's a package called classutilities (pip install classutilities), see the documentation here on PyPi.

Consider example:

import classutilities
class SomeClass(classutilities.ClassPropertiesMixin):
 _some_variable = 8 # Some encapsulated class variable
 @classutilities.classproperty
 def some_variable(cls): # class property getter
 return cls._some_variable
 @some_variable.setter
 def some_variable(cls, value): # class property setter
 cls._some_variable = value

You can use it on both class level and instance level:

# Getter on class level:
value = SomeClass.some_variable
print(value) # >>> 8
# Getter on instance level
inst = SomeClass()
value = inst.some_variable
print(value) # >>> 8
# Setter on class level:
new_value = 9
SomeClass.some_variable = new_value
print(SomeClass.some_variable) # >>> 9
print(SomeClass._some_variable) # >>> 9
# Setter on instance level
inst = SomeClass()
inst.some_variable = new_value
print(SomeClass.some_variable) # >>> 9
print(SomeClass._some_variable) # >>> 9
print(inst.some_variable) # >>> 9
print(inst._some_variable) # >>> 9

As you can see, it works correctly under all circumstances.

answered Jul 12, 2021 at 14:24

1 Comment

I tried a few other answers and this is what I've gone with as it seems to be best. It also keeps type checks and pylint happy if you put the @classmethod decorator under both @classproperty and .setter.
2

If you need the type hints, here's the answer (works with pyright):

from multiprocessing import RLock
from typing import TypeVar, Callable, Generic, Type
GetterReturnType = TypeVar("GetterReturnType")
class classproperty(Generic[GetterReturnType]):
 def __init__(self, func: Callable[..., GetterReturnType]):
 if isinstance(func, (classmethod, staticmethod)):
 fget = func
 else:
 fget = classmethod(func)
 self.fget = fget
 def __get__(self, obj, klass=None) -> GetterReturnType:
 if klass is None:
 klass = type(obj)
 return self.fget.__get__(obj, klass)()

If you need cached_classproperty (refer to the implementation of cached_property):

_NOT_FOUND = object()
class cached_classproperty(Generic[GetterReturnType], classproperty[GetterReturnType]):
 def __init__(self, func: Callable[..., GetterReturnType]):
 super().__init__(func)
 self.lock = RLock()
 def __set_name__(self, owner, name):
 self.attrname = f"__cached_classproperty_{name}"
 def __get__(self, obj, klass=None) -> GetterReturnType:
 val = getattr(klass, self.attrname, _NOT_FOUND)
 if val is _NOT_FOUND:
 with self.lock:
 # check if another thread filled cache while we awaited lock
 val = getattr(klass, self.attrname, _NOT_FOUND)
 if val is _NOT_FOUND:
 val = super().__get__(obj, klass)
 setattr(klass, self.attrname, val)
 return val # pyright: ignore[reportReturnType]

enter image description here

mkrieger1
24.1k7 gold badges67 silver badges83 bronze badges
answered Apr 19 at 9:22

Comments

1

Based on https://stackoverflow.com/a/1800999/2290820:

class MetaProperty(type):
 def __init__(cls, *args, **kwargs):
 super()
 @property
 def praparty(cls):
 return cls._var
 @praparty.setter
 def praparty(cls, val):
 cls._var = val
class A(metaclass=MetaProperty):
 _var = 5
print(A.praparty)
A.praparty = 6
print(A.praparty)
mkrieger1
24.1k7 gold badges67 silver badges83 bronze badges
answered Nov 12, 2021 at 0:01

Comments

0

I found a method to define a classproperty valid with Python 2 and 3.

from future.utils import with_metaclass
class BuilderMetaClass(type):
 @property
 def load_namespaces(self):
 return (self.__sourcepath__)
 
class BuilderMixin(with_metaclass(BuilderMetaClass, object)):
 __sourcepath__ = 'sp' 
print(BuilderMixin.load_namespaces)
mkrieger1
24.1k7 gold badges67 silver badges83 bronze badges
answered Oct 18, 2017 at 20:42

1 Comment

If this method is something you found somewhere, it would be good to give a link (see How to reference material written by others)
-1

Here is my solution that also caches the class property

class class_property(object):
 # this caches the result of the function call for fn with cls input
 # use this as a decorator on function methods that you want converted
 # into cached properties
 def __init__(self, fn):
 self._fn_name = fn.__name__
 if not isinstance(fn, (classmethod, staticmethod)):
 fn = classmethod(fn)
 self._fn = fn
 def __get__(self, obj, cls=None):
 if cls is None:
 cls = type(obj)
 if (
 self._fn_name in vars(cls) and
 type(vars(cls)[self._fn_name]).__name__ != "class_property"
 ):
 return vars(cls)[self._fn_name]
 else:
 value = self._fn.__get__(obj, cls)()
 setattr(cls, self._fn_name, value)
 return value
answered Oct 24, 2020 at 5:57

Comments

-49

Here's my suggestion. Don't use class methods.

Seriously.

What's the reason for using class methods in this case? Why not have an ordinary object of an ordinary class?


If you simply want to change the value, a property isn't really very helpful is it? Just set the attribute value and be done with it.

A property should only be used if there's something to conceal -- something that might change in a future implementation.

Maybe your example is way stripped down, and there is some hellish calculation you've left off. But it doesn't look like the property adds significant value.

The Java-influenced "privacy" techniques (in Python, attribute names that begin with _) aren't really very helpful. Private from whom? The point of private is a little nebulous when you have the source (as you do in Python.)

The Java-influenced EJB-style getters and setters (often done as properties in Python) are there to facilitate Java's primitive introspection as well as to pass muster with the static language compiler. All those getters and setters aren't as helpful in Python.

answered Sep 24, 2008 at 17:45

1 Comment

Because I need to modify an attribute that in such a way that is seen by all instances of a class, and in the scope from which these class methods are called does not have references to all instances of the class.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.