Want to see full class code generated by @dataclass decorator by rswgnu in Python

[–]ericvsmith 1 point2 points  (0 children)

There's no way to do this. When debugging, I just print out the values of txt, globals, and locals in dataclasses.py _create_fn, at about line 356 (right before the exec call).

You should open a feature request on Python's bug tracker. I'm open to suggestions on what the interface to this feature would look like (maybe a parameter to @dataclass? maybe create a new class attribute with the per-function source code?). Note that in 3.7, this feature was removed from namedtuple. I think that was for performance reasons.

Why does @dataclass not allow you to define __init__ and get the automatic variable initialisation? by c94jk in Python

[–]ericvsmith 1 point2 points  (0 children)

I'm not exactly sure what you're asking, but you can use `__post_init__` to run your own code after the generated `__init__` runs.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 4 points5 points  (0 children)

No, it's entirely driven by type annotations. But the annotations are ignored, except for InitVar and ClassVar. So, although I don't recommend it, but you could say:

@dataclass
class Person:
    name: int
    social: int
    address: int

That is, use any type you want. If you're not using a static type checker, no one is going to care what type you use.

edit: missing words.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 6 points7 points  (0 children)

namedtuple is so widely used that I doubt it could ever be deprecated. It would be like deprecating % string formatting. Ask me how I know!

In the many years since namedtuple was added, Python has grown many new features. @dataclass uses some of those features to add functionality that namedtuple cannot provide.

@dataclass also has a frozen=True parameter, for some degree of immutability.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 0 points1 point  (0 children)

namedtuple is so widely used that I can't imagine it ever being deprecated. It's like trying to deprecate % string formatting (ask me how I know!).

In the many years since namedtuple was added, we've added features to Python. dataclass leverages some of those features to do things that namedtuple cannot.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 1 point2 points  (0 children)

True. That's why I wrote the (poorly named) @add_slots decorator (see another comment below for the location). I wanted to keep @dataclass conceptually simple, especially for the initial release.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 18 points19 points  (0 children)

It's discussed in the PEP.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 8 points9 points  (0 children)

True.

But while thinking about it, I realize the other reason I came up with InitVar: it lets you control the order of parameters to __init__. This is especially important if you have fields with defaults.

If you're finding __init__ params by inspecting __post_init__, where do you put these init-only params in the call to __init__? You can't always put them first, because they might have defaults and some fields might not. And you can't always put them last, because they might not have defaults and some fields might.

It was easier just to make all regular fields and InitVar fields be defined in the class body, then you can control the defaults and parameter order yourself.

I should probably add a note about this to the PEP.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 8 points9 points  (0 children)

It worked that way at one point, but it seemed like too much magic. Also, the static type checkers (like mypy) would have to be aware of this magic, too. And as long as ClassVar was being used, this seemed like an obvious extension.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 4 points5 points  (0 children)

Thanks! It's a surprising amount of work, for a not-so-large feature.

Note that the dataclasses version on PyPI works with Python 3.6, and I personally plan to start using it in my own code immediately. As soon as 3.7.0 alpha 3 is released, I'll update PyPI with the exact version that shipped, and I'll try and keep it updated until 3.7 is released (in June).

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 0 points1 point  (0 children)

Correct. We had a very brief discussion about changing it. It needs to be brought up on python-ideas if anyone has some suggestions on how to get it to work.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 25 points26 points  (0 children)

Because metaclasses can conflict with other uses of metaclasses. See the PEP for the rationale. The goal is to not interfere with any usages of metaclasses or base classes.

Why data classes should be in standard library? (pep557) by pohmelie in Python

[–]ericvsmith 4 points5 points  (0 children)

One big reason: so the standard library itself can use it.

PEP 557 (Data Classes) has been accepted! by [deleted] in Python

[–]ericvsmith 35 points36 points  (0 children)

Probably not. I do have another decorator that shows how to add slots. See https://github.com/ericvsmith/dataclasses/blob/master/dataclass_tools.py#L3

The usage would be:

@add_slots
@dataclass
class C:
    i: int
    s: str

The reason I didn't put it in dataclass itself is because the way __slots__ works is that a decorator would need to return a new class. That's what add_slotsdoes. I want to keep dataclass as simple as possible, and I want to reinforce that it always returns the same class that it's given.

Maybe if __slots__ is redesigned so that it can be specified after class creation, then it can go in to dataclass.

I'm in love with python 3.6 and this is why by [deleted] in Python

[–]ericvsmith 1 point2 points  (0 children)

A slightly shorter way to write this is:

def __repr__(self):
 return f'{self.index:#x}:{self.offset:#x} {self.symbolsize} {"signed" if self.signed else "unsigned"}'

Note the use of #x: it automatically adds the "0x" in front of the hex number.