[Python-ideas] Trial balloon: adding variable type declarations in support of PEP 484

Daniel Moisset dmoisset at machinalis.com
Thu Aug 4 15:11:47 EDT 2016


On Thu, Aug 4, 2016 at 5:40 PM, Guido van Rossum <guido at python.org> wrote:

> On Thu, Aug 4, 2016 at 7:12 AM, Daniel Moisset <dmoisset at machinalis.com>
> wrote:
> > On Tue, Aug 2, 2016 at 11:09 PM, Guido van Rossum <guido at python.org>
> wrote:
> >> class C:
> >>     a: int  # instance var
> >>     b: List[int] = None  # instance var
> >>     c: class List[int] = []  # class var
> >>
> >
> > From that description I understand that after C is defined, C.__dict__
> will
> > contain the {'c': []} mapping... where us the {'b': None} mapping stored?
> > what's the runtime semantics that get it to every created instance?
> >
> > Or you are proposing that in runtime these are equivalent to "b, c =
> None,
> > []" ? If that's the case, I find it misleading to call them "instance
> > variables" vs "class variables", given that those concepts are supposed
> to
> > have different runtime semantics, not just for the typechecker.
>
> The latter (except possibly for also storing the types in __annotations__).
>
> I'm a little worried by your claim that it's misleading to distinguish
> between instance and class variables. There really are three
> categories:
>

For me what's misleading is the runtime behaviour for b, which has na
initializer but is not flagged as class variable... see below


>
> - pure class variable -- exists in class __dict__ only
> - pure instance variable -- exists in instance __dict__ only
> - instance variable with class default -- in class __dict__ and maybe
> in instance __dict__
>
> (Note that even a pure class variable can be referenced as an instance
> attribute -- this is the mechanism that enables the third category.)
>
> Pragmatically, the two categories of instance variables together are
> wildly more common than pure class variables. I also believe that the
> two categories of instance variables are both pretty common. So I want
> the notation to support all three:
>
> class Starship:
>     stats: class Dict[str, int] = {}  # Pure class variable
>     damage: class int = 0  # Hybrid class/instance variable
>     captain: str  # Pure instance variable
>
> The intention is that the captain's name must always be set when a
> Starship is initialized, but all Starships start their life with zero
> damage, and stats is merely a place where various Starship methods can
> leave behind counters logging how often various events occur. (In real
> code it would probably be a defaultdict.)
>


I follow the example perfectly. Now suppose a reader finds the following
piece of code:

class Starship:
    stats: class Dict[str, int] = {}  # Pure class variable
    damage: class int = 0  # Hybrid class/instance variable
    captain: str  # Pure instance variable
    speed: float = 0

I added a new attribute (similar to b in your original example). Given that
the type declaration doesn't say "class",the reader might be inclined to
think it's an instance variable. But in runtime (if I got you right), that
variable will be stored in "Starship.__dict__" and writing "Starship.speed
= 3" will change the speed of those starship instances that still haven't
set the attribute. So in the end both "damage" and "speed" have "class
variable" runtime semantics, even when one is flagged as "class" and the
other isn't.

The other combination that feels a bit confusing when adding "class" tags
is saying "attr: class T", without an initializer.... in what case would
someone do that? what does it mean if I find some code saying that about
the class, that it might get that attribute set somewhere else?



-- 
Daniel F. Moisset - UK Country Manager
www.machinalis.com
Skype: @dmoisset
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160804/03f26d32/attachment-0001.html>


More information about the Python-ideas mailing list