Hello! In the past few months I've been toying around with .NET, C# and PythonNet. While I still think that C# is too wory (public static explicit operator Egg(Spam spam) { ... }) C# has one syntax feature I really like to see in Python. private float _a public float a { get { return _a; } set { _a = value; } } I think it's a very nice way to define a variable that acts similar to Python properties. get, set and value are part of the syntax. Python has no nice way to define a property with set and get. You always have to use lambda or some private methods. class Now: _a = 0.0 @property def a(self): """Read only property return self._a def _geta(self): return self._a def _seta(self, value): self._a = value a = property(_geta, _seta) It puts a lot of methods into the body of the class that are only used for properties. I find the C# syntax more intriguing. It puts the getter and setter into a block of their own and makes reading and understand the property more easy. What do you think about this syntax? class EasyExample: _a = 0.0 property a: """doc string """ def get(self) -> float: return self._a def set(self, value): self._a = float(value) def delete(self): del self._a It may be possible to combine the feature with generic methods but I guess that's not going to be easy. class ComplexExample: _a = 0.0 property a: """doc string """ def get(self) -> float: return self._a @generic def set(self, value:float): self._a = value @generic def set(self, value:int): self._a = float(value) @generic def set(self, value:str): self._a = float(value) def delete(self): del self._a An alternative syntax. It doesn't look as clean as the other syntax but has the benefit that the variable is in front of the definition. class AlternativeSyntax: _a = 0.0 a = property: """doc string """ Comments? Christian
On 7/12/07, Christian Heimes <lists@cheimes.de> wrote:
What do you think about this syntax?
class EasyExample: _a = 0.0 property a: """doc string """ def get(self) -> float: return self._a def set(self, value): self._a = float(value) def delete(self): del self._a
I'm pretty sure Guido's said before that he doesn't like the get/set/del methods being indented more than other instance methods would be. If you really like this style, you can get something like it today using inner classes: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418 Steve -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy
On 7/12/07, Steven Bethard <steven.bethard@gmail.com> wrote:
On 7/12/07, Christian Heimes <lists@cheimes.de> wrote:
What do you think about this syntax?
class EasyExample: _a = 0.0 property a: """doc string """ def get(self) -> float: return self._a def set(self, value): self._a = float(value) def delete(self): del self._a
I'm pretty sure Guido's said before that he doesn't like the get/set/del methods being indented more than other instance methods would be. If you really like this style, you can get something like it today using inner classes:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418
Or decorators: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698 George -- "If I have been able to see further, it was only because I stood on the shoulders of million monkeys."
Christian Heimes <lists@cheimes.de> wrote:
Hello!
In the past few months I've been toying around with .NET, C# and PythonNet. While I still think that C# is too wory (public static explicit operator Egg(Spam spam) { ... }) C# has one syntax feature I really like to see in Python.
private float _a public float a { get { return _a; } set { _a = value; } }
[snip]
Comments?
Python has an exact equivalent to the C# method (which uses a new block/scope for defining properties...) class foo: class a(Property): ''' documentation ''' def get(self): return self._a def set(self, val): self._a = val def de1(self): del self._a Now all you need is a Property base class with a proper metaclass that handles all of the magic for you. I'm curious as to why this still gets brought up when the obvious syntax is more or less identical to basically all reasonable alternate syntaxes. Is it because people don't understand that metaclasses can mangle your class any way they want? - Josiah
Josiah Carlson schrieb:
Christian Heimes <lists@cheimes.de> wrote:
Hello!
In the past few months I've been toying around with .NET, C# and PythonNet. While I still think that C# is too wory (public static explicit operator Egg(Spam spam) { ... }) C# has one syntax feature I really like to see in Python.
private float _a public float a { get { return _a; } set { _a = value; } }
[snip]
Comments?
Python has an exact equivalent to the C# method (which uses a new block/scope for defining properties...)
class foo: class a(Property): ''' documentation ''' def get(self): return self._a def set(self, val): self._a = val def de1(self): del self._a
Now all you need is a Property base class with a proper metaclass that handles all of the magic for you. I'm curious as to why this still gets brought up when the obvious syntax is more or less identical to basically all reasonable alternate syntaxes. Is it because people don't understand that metaclasses can mangle your class any way they want?
No, it's because they feel that the word "class" to introduce a property is ugly, and I can't blame them for it. Georg
Georg Brandl wrote:
No, it's because they feel that the word "class" to introduce a property is ugly, and I can't blame them for it.
Yeah, it looks ugly, it's hard to understand if you aren't familiar with the technique and it doesn't integrate into documentation tools like pydoc. The trick isn't part of Python's stdlib, too. I like to see a clean solution that is easy to understand and not a genius but tricky metaclass hack. Christian
Josiah Carlson wrote:
class foo: class a(Property): ''' documentation ''' def get(self): return self._a ...
I'm curious as to why this still gets brought up when the obvious syntax is more or less identical to basically all reasonable alternate syntaxes.
I would dispute that anything involving a class statement that creates something other than a class is "obvious". -- Greg
Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Josiah Carlson wrote:
class foo: class a(Property): ''' documentation ''' def get(self): return self._a ...
I'm curious as to why this still gets brought up when the obvious syntax is more or less identical to basically all reasonable alternate syntaxes.
I would dispute that anything involving a class statement that creates something other than a class is "obvious".
The "Property" statement that is longer, the existance of get/set/de1 methods, those didn't catch your eye? What if the user plopped in a nice big "__metaclass__ = Property" line? Ugly or not, I find that it has helped me organize (with indentation), not repeat myself, and not have to clean up spare get/set/del methods. I personally prefer it to x = property(...), a property decorator, and a bazillion times more than any property-specific syntax. - Josiah
Josiah Carlson wrote:
Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Josiah Carlson wrote:
class foo: class a(Property): ''' documentation ''' def get(self): return self._a ...
I'm curious as to why this still gets brought up when the obvious syntax is more or less identical to basically all reasonable alternate syntaxes.
I would dispute that anything involving a class statement that creates something other than a class is "obvious".
The "Property" statement that is longer, the existance of get/set/de1 methods, those didn't catch your eye? What if the user plopped in a nice big "__metaclass__ = Property" line? Ugly or not, I find that it has helped me organize (with indentation), not repeat myself, and not have to clean up spare get/set/del methods. I personally prefer it to x = property(...), a property decorator, and a bazillion times more than any property-specific syntax.
Your original question was on how obvious this is to *invent*, but here you're defending how obvious it is to *read*. (FWIW, I think it reads just fine, and I've added a couple of new, nifty things to my personal library. Thanks for the pointer.) Inner-class-as-a-class-variable is the mental leap you have to make, plus you have to be comfortable with metaclasses. I expect most developers would get to "hey, let's add a new keyword" before they arrive at that. Some proportion of those would bring it up on a mailing list, and then some proportion of the mailing list recipients would have seen it before, and some proportion of those recipients might feel a little exasperated and wonder how the rest of us can be so blind as to miss such an obvious solution... It's statistics, babay. On a very related topic, I find it interesting how often classes get abused just to provide a convenient namespace to stick things in. Classes are heavy things, though, with a lot of semantics and behind-the-scenes witchery to deal with inheritance and metaclasses and such-like. Why bring that baggage into it? It might be nice to be able to declare a one-off namespace: class Foo: x: '''documentation''' def __get__(self, instance, owner): # self = x, instance = a Foo(), owner = Foo() return instance._x logger: '''Singleton logger object blah blah...''' db = make_db_connection(...) def log(self, message): ... Be gentle, because I haven't thought this through very well. :) Neil
On 7/13/07, Neil Toronto <ntoronto@cs.byu.edu> wrote:
On a very related topic, I find it interesting how often classes get abused just to provide a convenient namespace to stick things in. Classes are heavy things, though, with a lot of semantics and behind-the-scenes witchery to deal with inheritance and metaclasses and such-like. Why bring that baggage into it? It might be nice to be able to declare a one-off namespace:
class Foo: x: '''documentation''' def __get__(self, instance, owner): # self = x, instance = a Foo(), owner = Foo() return instance._x
logger: '''Singleton logger object blah blah...''' db = make_db_connection(...)
def log(self, message): ...
You should look at the "make" statement PEP, which offered you something like this: http://www.python.org/dev/peps/pep-0359/ It was withdrawn at Guido's request - partly because he didn't like how it allowed you to indent the methods for properties. STeVe -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy
Neil Toronto wrote:
Inner-class-as-a-class-variable is the mental leap you have to make, plus you have to be comfortable with metaclasses.
Actually, I think there's a further mental leap you have to make -- the notion that a 'class' statement can create something that is *not* a class. Just knowing that there is a metaclass involved is not enough to alert you to this possibility. IMO this is something that should definitely not be encouraged, as it directly obfuscates the code -- you're saying 'class' when you don't really mean it.
It might be nice to be able to declare a one-off namespace:
Yes, things like this have been suggested before. There was a thread not long ago about a 'make' statement, for example, and there have been numerous suggestions for a 'namespace' statement. My favourite version would be something like intance foo(property): def __get__(self): ... def __set__(self, x): ... which would be roughly equivalent to class _foo(property): ... foo = _foo() but without the intermediate class name. -- Greg
Greg Ewing wrote:
Neil Toronto wrote:
It might be nice to be able to declare a one-off namespace:
Yes, things like this have been suggested before. There was a thread not long ago about a 'make' statement, for example, and there have been numerous suggestions for a 'namespace' statement.
My favourite version would be something like
intance foo(property):
def __get__(self): ...
def __set__(self, x): ...
Surely you meant to write "instance". :) I like that spelling. The keyword has exactly the right meaning. I imagine having to create a new keyword just for a bit of syntactic sugar would be the main argument against it. It's not just about saving keystrokes, though.
which would be roughly equivalent to
class _foo(property): ...
foo = _foo()
but without the intermediate class name.
Seems this sort of thing would be trivial with a class decorator, something like "@instance" or "@oneinstance". ("@singleton" would probably make people expect a call to the class to return a unique instance only the first time.) As part of my new delvination (that's a word) into metaclasses, I've been trying to make a metaclass that does the same thing. (No spoilers, please!) Neil
Neil Toronto wrote:
Greg Ewing wrote:
intance foo(property):
Surely you meant to write "instance". :)
Oops, yes.
Seems this sort of thing would be trivial with a class decorator, something like "@instance" or "@oneinstance".
I have much the same feeling about class decorators that don't return a class. You're still writing 'class foo' yet not defining foo to be a class. -- Greg
participants (7)
-
Christian Heimes
-
Georg Brandl
-
George Sakkis
-
Greg Ewing
-
Josiah Carlson
-
Neil Toronto
-
Steven Bethard