@classproperty, @abc.abstractclasspropery, etc.
There's a whole matrix of these and I'm wondering why the matrix is currently sparse rather than implementing them all. Or rather, why we can't stack them as: class foo(object): @classmethod @property def bar(cls, ...): ... Essentially the permutation are, I think: {'unadorned'|abc.abstract}{'normal'|static|class}{method|property|non-callable attribute}. concreteness implicit first arg type name comments {unadorned} {unadorned} method def foo(): exists now {unadorned} {unadorned} property @property exists now {unadorned} {unadorned} non-callable attribute x = 2 exists now {unadorned} static method @staticmethod exists now {unadorned} static property @staticproperty proposing {unadorned} static non-callable attribute {degenerate case - variables don't have arguments} unnecessary {unadorned} class method @classmethod exists now {unadorned} class property @classproperty or @classmethod;@property proposing {unadorned} class non-callable attribute {degenerate case - variables don't have arguments} unnecessary abc.abstract {unadorned} method @abc.abstractmethod exists now abc.abstract {unadorned} property @abc.abstractproperty exists now abc.abstract {unadorned} non-callable attribute @abc.abstractattribute or @abc.abstract;@attribute proposing abc.abstract static method @abc.abstractstaticmethod exists now abc.abstract static property @abc.staticproperty proposing abc.abstract static non-callable attribute {degenerate case - variables don't have arguments} unnecessary abc.abstract class method @abc.abstractclassmethod exists now abc.abstract class property @abc.abstractclassproperty proposing abc.abstract class non-callable attribute {degenerate case - variables don't have arguments} unnecessary I think the meanings of the new ones are pretty straightforward, but in case they are not... @staticproperty - like @property only without an implicit first argument. Allows the property to be called directly from the class without requiring a throw-away instance. @classproperty - like @property, only the implicit first argument to the method is the class. Allows the property to be called directly from the class without requiring a throw-away instance. @abc.abstractattribute - a simple, non-callable variable that must be overridden in subclasses @abc.abstractstaticproperty - like @abc.abstractproperty only for @staticproperty @abc.abstractclassproperty - like @abc.abstractproperty only for @classproperty --rich
On Mon, Jan 3, 2011 at 22:09, K. Richard Pixley <rich@noir.com> wrote:
I think the meanings of the new ones are pretty straightforward, but in case they are not...
@staticproperty - like @property only without an implicit first argument. Allows the property to be called directly from the class without requiring a throw-away instance.
@classproperty - like @property, only the implicit first argument to the method is the class. Allows the property to be called directly from the class without requiring a throw-away instance.
@abc.abstractattribute - a simple, non-callable variable that must be overridden in subclasses
@abc.abstractstaticproperty - like @abc.abstractproperty only for @staticproperty
@abc.abstractclassproperty - like @abc.abstractproperty only for @classproperty
Do you have actual use cases for these? Cheers, Dirkjan
On 20110103 13:22, Dirkjan Ochtman wrote:
On Mon, Jan 3, 2011 at 22:09, K. Richard Pixley<rich@noir.com> wrote:
I think the meanings of the new ones are pretty straightforward, but in case they are not...
@staticproperty - like @property only without an implicit first argument. Allows the property to be called directly from the class without requiring a throw-away instance.
@classproperty - like @property, only the implicit first argument to the method is the class. Allows the property to be called directly from the class without requiring a throw-away instance.
@abc.abstractattribute - a simple, non-callable variable that must be overridden in subclasses
@abc.abstractstaticproperty - like @abc.abstractproperty only for @staticproperty
@abc.abstractclassproperty - like @abc.abstractproperty only for @classproperty Do you have actual use cases for these? Yes. Here's a toy example for abstractclassproperty:
class InstanceKeeper(object): __metaclass__ = abc.ABCMeta @abc.abstractclassproperty def all_instances(cls): raise NotImplementedError class InstancesByList(InstanceKeeper): instances = [] @classproperty def all_instances(cls): return cls.instances class InstancesByDict(InstanceKeeper): instances = {} @classproperty def all_instances(cls): return list(cls.instances) class WhateversByList(InstancesByList): instances = [] ... class OthersByList(InstancesByList): instances = [] ... class StillMoreByDict(InstancesByDict): instances = {} ... class MoreAgainByDict(InstancesByDict): instances = {} ... I'm working on a library for reading and writing ELF format object files. I have a bunch of classes representing various structs. And the structs have, or point to, other structs. I'm using different subclasses to describe different byte ordering, (endianness), and word size, (32 vs 64 bit). Here are examples for the others. class Codable(object): __metaclass__ = abc.ABCMeta @abc.abstractattribute coder = None @classproperty def size(cls): return cls.coder.size class FileHeader(Codable): __metaclass__ = abc.ABCMeta @abc.abstractattribute sectionHeaderClass = None """ Used to create new instances. """" sectionHeader = None @abc.abstractstaticproperty def word_size(): raise NotImplementedError def __new__(...): """ factory function reading the first few bytes and returning an instance of one of the subclasses """ ... def __init__(self, ...): ... self.sectionHeader = self.sectionHeaderClass(...) class Bit64(object): @staticproperty def word_size(): return 64 class Bit32(object): @staticproperty def word_size(): return 32 class FileHeader64l(FileHeader, Bit64): coder = struct.Struct(...) sectionHeaderClass = SectionHeader64l class FileHeader64b(FileHeader, Bit64): coder = struct.Struct(...) sectionHeaderClass = SectionHeader64b class FileHeader32l(FileHeader, Bit32): coder = struct.Struct(...) sectionHeaderClass = SectionHeader32l class FileHeader32b(FileHeader, Bit32): coder = struct.Struct(...) sectionHeaderClass = SectionHeader32b class SectionHeader(Codable): __metaclass__ = ABCMeta @abc.abstractattribute subsectionHeaderClass = None ... class SectionHeader64l(SectionHeader, Bit64): coder = struct.Struct(...) .... --rich
On 20110103 13:22, Dirkjan Ochtman wrote:
Do you have actual use cases for these?
On Mon, Jan 3, 2011 at 2:06 PM, K. Richard Pixley <rich@noir.com> wrote:
Yes. Here's a toy example for abstractclassproperty:
Um, a toy example is pretty much the opposite of a use case. :-( That said, I am sure there are use cases for static property and class property -- I've run into them myself. An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here. -- --Guido van Rossum (python.org/~guido)
On 4 January 2011 00:56, Guido van Rossum <guido@python.org> wrote:
On 20110103 13:22, Dirkjan Ochtman wrote:
Do you have actual use cases for these?
On Mon, Jan 3, 2011 at 2:06 PM, K. Richard Pixley <rich@noir.com> wrote:
Yes. Here's a toy example for abstractclassproperty:
Um, a toy example is pretty much the opposite of a use case. :-(
That said, I am sure there are use cases for static property and class property -- I've run into them myself.
An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here.
A class property that can be fetched is very easy to implement. Because of asymmetry in the descriptor protocol I don't think you can create a class property with behaviour on set though (unless you use a metaclass I guess). class classproperty(object): def __init__(self, function): self._function = function def __get__(self, instance, owner): return self._function(owner) All the best, Michael
-- --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>) _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- http://www.voidspace.org.uk/ May you do good and not evil May you find forgiveness for yourself and forgive others May you share freely, never taking more than you give. -- the sqlite blessing http://www.sqlite.org/different.html
On Mon, Jan 3, 2011 at 7:56 PM, Guido van Rossum <guido@python.org> wrote:
That said, I am sure there are use cases for static property and class property -- I've run into them myself.
An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here.
-- --Guido van Rossum (python.org/~guido)
This attitude seems to go against the we're-all-adults-here attitude that Python, for better or worse, really wants us to take. If we want to turn "there's no good reason to do X; it's pointless and you'd have to be insane to try, and I even documented that you can't do it" into "it's programmability enforced that you can't do X", it seems like we should be migrating to a language that enforces this with nicer syntax, more fidelity, and less overhead. Mike
On 4 January 2011 15:31, Mike Graham <mikegraham@gmail.com> wrote:
On Mon, Jan 3, 2011 at 7:56 PM, Guido van Rossum <guido@python.org> wrote:
That said, I am sure there are use cases for static property and class property -- I've run into them myself.
An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here.
I'm not entirely sure what you're referring to here - but if you're referring to the desire to make an attribute read-only then there is a different principle at work. If setting something is a programmer error, then it is better that the error become an exception at the point the error is made rather than become a different exception somewhere else later on. Michael Foord
-- --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)
This attitude seems to go against the we're-all-adults-here attitude that Python, for better or worse, really wants us to take. If we want to turn "there's no good reason to do X; it's pointless and you'd have to be insane to try, and I even documented that you can't do it" into "it's programmability enforced that you can't do X", it seems like we should be migrating to a language that enforces this with nicer syntax, more fidelity, and less overhead.
Mike _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- http://www.voidspace.org.uk/ May you do good and not evil May you find forgiveness for yourself and forgive others May you share freely, never taking more than you give. -- the sqlite blessing http://www.sqlite.org/different.html
On 1/4/11 07:31 , Mike Graham wrote:
That said, I am sure there are use cases for static property and class property -- I've run into them myself.
An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here.
-- --Guido van Rossum (python.org/~guido) This attitude seems to go against the we're-all-adults-here attitude
On Mon, Jan 3, 2011 at 7:56 PM, Guido van Rossum<guido@python.org> wrote: that Python, for better or worse, really wants us to take. If we want to turn "there's no good reason to do X; it's pointless and you'd have to be insane to try, and I even documented that you can't do it" into "it's programmability enforced that you can't do X", it seems like we should be migrating to a language that enforces this with nicer syntax, more fidelity, and less overhead. It's not the restriction that I'm looking for - it's the expressive grace.
These concepts are pretty straightforward given the beginnings of them that we have now. Filling out the matrix is a pretty obvious concept. The idea that while the concepts are available to anyone, straightforward, and recur, but can only be implemented by someone with extremely current and advanced knowledge of the interpreter, resulting in code which is less transparent rather than more, is the restrictive idea. --rich
04.01.11 02:56, Guido van Rossum пише:
That said, I am sure there are use cases for static property and class property -- I've run into them myself.
An example use case for class property: in App Engine, we have a Model class (it's similar to Django's Model class). A model has a "kind" which is a string (it's the equivalent of an SQL table name). The kind is usually the class name but sometimes there's a need to override it. However once the class is defined it should be considered read-only. Currently our choices are to make this an instance property (but there are some situations where we don't have an instance, e.g. when creating a new instance using a class method); or to make it a class attribute (but this isn't read-only); or to make it a class method (which requires the user to write M.kind() instead of M.kind). If I had class properties I'd use one here.
Try to combine classmethod and property:
class A: ... @classmethod ... @property ... def name(cls): ... return cls.__name__ ... A.name 'A'
And as you said, classmethod supersedes staticmethod. The only strong use case for staticmethod that I know is to make a Python function a class attribute without making it a method. And for static property there is no even such use case.
On Tue, Jan 4, 2011 at 7:09 AM, K. Richard Pixley <rich@noir.com> wrote:
I think the meanings of the new ones are pretty straightforward, but in case they are not...
@staticproperty - like @property only without an implicit first argument. Allows the property to be called directly from the class without requiring a throw-away instance.
@classproperty - like @property, only the implicit first argument to the method is the class. Allows the property to be called directly from the class without requiring a throw-away instance.
As Michael mentions later in the thread, these can't really work due to the asymmetry in the descriptor protocol: if you retrieve a descriptor object directly from a class, the interpreter will consult the __get__ method of that descriptor, but if you set or delete it through the class, it will just perform the set or delete - the descriptor has no say in the matter, even if it defines __set__ or __delete__ methods. (See the example interpreter session at http://pastebin.com/1M7KYB9d). The only way to get static or class properties to work correctly is to define them on the metaclass, in which case you can just use the existing property descriptor (although you have to then jump through additional hoops to make access via instances work properly - off the top of my head, I'm actually not sure how to make that happen). @abc.abstractattribute - a simple, non-callable variable that must be
overridden in subclasses
You can't decorate attributes, only functions.
@abc.abstractstaticproperty - like @abc.abstractproperty only for @staticproperty
@abc.abstractclassproperty - like @abc.abstractproperty only for @classproperty
See above. These don't exist because staticproperty and classproperty don't work. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Mon, Jan 3, 2011 at 4:09 PM, K. Richard Pixley <rich@noir.com> wrote:
Essentially the permutation are, I think: {'unadorned'|abc.abstract}{'normal'|static|class}{method|property|non-callable attribute}.
At the abstract level, a property and a normal, non-callable attribute are the same thing. Mike
On Mon, Jan 3, 2011 at 4:09 PM, K. Richard Pixley <rich@noir.com <mailto:rich@noir.com>> wrote:
Essentially the permutation are, I think: {'unadorned'|abc.abstract}{'normal'|static|class}{method|property|non-callable attribute}.
At the abstract level, a property and a normal, non-callable attribute are the same thing. They are from the instantiation perspective but not from the subclassing
On 1/4/11 07:23 , Mike Graham wrote: perspective. From the subclassing perspective, it's the difference between: class Foo(object): @property def bar(self): ... and: class Foo(object): bar = ... If an abstract property were to be answered by a simple assignment, then the "read-only" trait would be lost. --rich
Old thread, pity it didn't get any traction. I second this. Except perhaps the @staticproperty: since a static (method|property) is bound to neither the instance nor the class, it doesn't seem straightforward/intuitive as to where the value set in the setter should go. E.g. if it sets an attribute in the class that defined the @staticproperty, then that class' attribute could be modified through a subclass or a subclass' instance by doing `obj.prop = value` which seems like too much of "spooky action at a distance` (since a static attribute is by definition bound to the class and only the identical class, not any subclasses or instances).
On Wed, Dec 16, 2020 at 12:16:46AM -0000, Paolo Lammens wrote:
Old thread, pity it didn't get any traction. I second this.
It is a thread from 2011. Do you think people will remember what it is about, or still have it in their inboxes? At this point, you should start a new thread (and link back to the original) rather than try to resurrect a nearly nine year old discussion. If you do intend to restart this discussion, please don't assume that we all know, or agree, with your definitions of "staticproperty" etc. Remember that the meaning of "static method" in Python and in other languages are not necessarily the same. Thank you. -- Steve
03.01.11 23:09, K. Richard Pixley пише:
There's a whole matrix of these and I'm wondering why the matrix is currently sparse rather than implementing them all. Or rather, why we can't stack them as:
class foo(object): @classmethod @property def bar(cls, ...): ...
You can. And you can add also abstractmethod. Not all combinations work in arbitrary order, but you can find the right order if it makes any sense. Things like abstractclassmethod are legacy. It is more preferable to combine elemental decorators.
On 12/16/20 1:31 AM, Serhiy Storchaka wrote:
Things like abstractclassmethod are legacy. It is more preferable to combine elemental decorators.
I completely disagree, although I suppose the determining factor is one's point of view. I see it as "abstractclassmethod" being its own thing, and while it can be composed from "abstract" and "classmethod", nothing is gained by splitting those words across multiple lines. -- ~Ethan~
participants (10)
-
Dirkjan Ochtman
-
Ethan Furman
-
Guido van Rossum
-
K. Richard Pixley
-
Michael Foord
-
Mike Graham
-
Nick Coghlan
-
Paolo Lammens
-
Serhiy Storchaka
-
Steven D'Aprano