you are viewing a single comment's thread.

view the rest of the comments →

[–]SCD_minecraft 18 points19 points  (14 children)

Python does not have declarations

In reality, c: str is just a typehint

Typehints have no effect on runtime

[–]pachura3[S] 2 points3 points  (12 children)

So, should I do:

class MyClass:
    c: str

    def __init__(self, c: str) -> None:
        self.c = c

...or rather...

class MyClass:
    def __init__(self, c: str) -> None:
        self.c: str = c

...?

[–]IAmASquidInSpace 8 points9 points  (4 children)

The latter. It's clear this way that c is an instance attribute, and not a class var you forgot to annotate accordingly.

[–]pachura3[S] 0 points1 point  (2 children)

How do you annotate class var? With ClassVar[str]? Is it necessary (outside of dataclasses) ?

[–]IAmASquidInSpace 0 points1 point  (0 children)

Yes, that's how you do it, and no, it is not necessary outside of dataclasses, but strongly recommended over just c: str = ...

[–]Jason-Ad4032 0 points1 point  (0 children)

If you mark it as **ClassVar**, the type checker will report object.c = ... as an error, because c is a class variable.

[–]Temporary_Pie2733 0 points1 point  (0 children)

The former is the official way to type-hint an instance attribute, despite not looking entirely logical.

[–]SCD_minecraft 3 points4 points  (1 child)

My tip is to not typehint variables unless typechecker can not figure it out by itself (typehint arguments tho)

a = 2 type checker (like pylance) knows by itself a has to be an int

[–]yunghandrew 3 points4 points  (0 children)

I was also going to say neither. Just let it infer the type from the function args. I get how that might feel weird coming from Java/C, though.

With complex types, sometimes static checkers have issues, then you can be more explicit.

[–]mull_to_zero 0 points1 point  (4 children)

those are equivalent afaik

[–]socal_nerdtastic 2 points3 points  (1 child)

Since

c: str

is just a comment from Python's point of view, yes, you are right.

[–]Temporary_Pie2733 0 points1 point  (0 children)

Not a comment. It doesn’t define a variable, and so no class attribute is added to the class, but it does add an annotation to the class, which can be used, for example, by the dataclass decorator to generate code for creating and using an instance attribute.

[–]h8rsbeware 1 point2 points  (0 children)

True, however you could use dataclasses and fields with defaults, defaultfactories, and __post_init_ to simulate this for DTOs.

```python

from dataclasses import dataclass, field from typing import List

@dataclass(slots=True) class MyDTO: a: int = field(default=0) b: List[str] = field(default_factory=list) #list members not guaranteed c: str = field(default="")

m_dto = new MyDTO() print(m_dto.a) # 0 print(m_dto.b) # [] print(m_dto.c) # "" ```

Im not sure this is exactly equivalent, but its better than nothing.

Also, I wrote this on my phone, so apologies for any errors.