[Python-Dev] PEP 526 ready for review: Syntax for Variable and Attribute Annotations
Steven D'Aprano
steve at pearwood.info
Thu Sep 1 12:21:18 EDT 2016
On Thu, Sep 01, 2016 at 04:11:05PM +0300, Koos Zevenhoven wrote:
> Maybe it's just me, but I've always thought 'def' is Python's least
> logically used keyword. It seems to come from 'define', but what is it
> about 'define' that makes it relate to functions only.
Convention.
You can't use "def" to define both functions and classes:
def function(x): ...
def Class(x): ...
is ambiguous, which is the function and which is the class? So we cannot
avoid at least one limitation: "def is for functions, or classes, but
not both". Given that, it isn't that weird to make the rule "def is only
for functions".
[...]
> Note that we could then also have this:
>
> def NAME
>
> Which would, again for readability (see above), be a way to express
> that "there is an instance variable called X, but no type hint for
> now". I can't think of a *good* way to do this with the keyword-free
> version for people that don't use type hints.
The simplest way would be to say "go on, one type hint won't hurt,
there's no meaningful runtime cost, just do it".
from typing import Any
class X:
NAME: Any
Since I'm not running a type checker, it doesn't matter what hint I use,
but Any is probably the least inaccurate.
But I think there's a better way.
Unless I've missed something, there's no way to pre-declare an instance
attribute without specifying a type. (Even if that type is Any.) So how
about we allow None as a type-hint on its own:
NAME: None
as equivalent to a declaration *without* a hint. The reader, and the
type-checker, can see that there's an instance attribute called NAME,
but in the absense of an actual hint, the type will have to be inferred,
just as if it wasn't declared at all.
The risk is that somebody will "helpfully" correct the "obvious typo"
and change it to NAME = None, but I think that will usually be harmless.
I can invent examples where they will behave differently, but they feel
contrived to me:
class X:
spam: None # declaration only, without a hint
def method(self):
if not hasattr(self, "spam"):
raise XError("spam not set")
return self.spam
def setup(self, arg):
if hasattr(self, "spam"):
raise XError("spam already set")
self.spam = arg
Changing the declaration to an assignment does change the behaviour of
the class, but I think that will be obvious when it happens.
--
Steve
More information about the Python-Dev
mailing list