#๐Ÿ”’ Dataclass property that is evaluated at runtime depending on another prop

40 messages ยท Page 1 of 1 (latest)

feral finchBOT
#

@grizzled edge

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

hazy kiln
#

you'll have to use @property. and name it is_valid, not isValid

#

!property

#

we don't have a property tag?
lame

#

!docs property

feral finchBOT
#

class property(fget=None, fset=None, fdel=None, doc=None)```
Return a property attribute.

*fget* is a function for getting an attribute value. *fset* is a function for setting an attribute value. *fdel* is a function for deleting an attribute value. And *doc* creates a docstring for the attribute.

A typical use is to define a managed attribute `x`...
hazy kiln
#

evaluated at runtime
Classes are created at runtime. You might mean "at instance creation time". Which might seem like a pedantic distinction, but it isn't.

#

oh, you can also call __post_init__

#

__post_init__ is basically just a second init method that's called immediately after the one created dynamically by the dataclass decorator.

#

what do you think, @grizzled edge?

#

Dataclasses are a shorthand for when you don't need very much (or any) custom logic. It might be that they're the wrong choice for what you're trying to do.

#

!e

from dataclasses import dataclass

@dataclass
class A:
  prop1: str
  prop2: str


@dataclass
class B(A):
  prop3: str

b = B('a', 'b', 'c')
print(b)
feral finchBOT
#

@hazy kiln :white_check_mark: Your 3.12 eval job has completed with return code 0.

B(prop1='a', prop2='b', prop3='c')
hazy kiln
#

hm, good.

feral finchBOT
#

@grizzled edge :x: Your 3.12 eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "/home/main.py", line 14, in <module>
003 |     b = B(A, 'Z')
004 |         ^^^^^^^^^
005 | TypeError: B.__init__() missing 1 required positional argument: 'prop3'
hazy kiln
#

The first argument for B has to be a value for prop1. What were you expecting?

#

deconstruct the base class?

#

also, keep in mind that you've passed A, the class itself. not a.

#

is that what you meant to do?

#

you've passed A, the class itself. not a. is that what you meant to do?

#

B.__init__ expects three values: the two attributes for instances of A, and one for B. If you want more than one way of creating an instance of B, you should use classmethod constructors.

#

you make your own init method that expects an instance of a parent class of B

#

at that point, you could have something like self.__dict__.update(base.__dict__). which is a problem, since it hides what the attributes of the newly created object will be

#

but self.__dict__.update(base.__dict__) will copy all the attribute-value pairs from base over to self.

#

I was suggesting that you put it in the init method for B.

#

if your plan is to create instances of B with an instance of A, and some number of additional attributes.

hazy kiln
feral finchBOT
#

@grizzled edge :x: Your 3.12 eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "/home/main.py", line 1, in <module>
003 |     @dataclass
004 |      ^^^^^^^^^
005 | NameError: name 'dataclass' is not defined
#

@grizzled edge :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | A(prop1='a', prop2='b')
002 | B(prop1='a', prop2='b')
hazy kiln
#

the problem isn't that b.prop3 isn't defined. it's that B.__str__ is A.__str__, because B isn't a dataclass and doesn't re-define its own str method.

#

!e

from dataclasses import dataclass

@dataclass
class A:
    prop1: str
    prop2: str

class B(A):
    # prop3: bool -- this line shouldn't be here.

    def __init__(self, base: A):
        self.__dict__.update(base.__dict__)
        self.prop3 = (base.prop1 == 'a')

a = A('a', 'b')
b = B(a)

print(a)
print(b)
print(b.prop3)
feral finchBOT
#

@hazy kiln :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | A(prop1='a', prop2='b')
002 | B(prop1='a', prop2='b')
003 | True
hazy kiln
#

the !e has to be at the beginning of the message. and you can't edit the message retroactively.

#

(that is, the bot only recognizes if a message is a command when it's posted the first time.)

#

!e

from dataclasses import dataclass

@dataclass
class A:
    prop1: str
    prop2: str

@dataclass
class B(A):
    prop3: bool

    def __init__(self, base: A):
        self.__dict__.update(base.__dict__)
        self.prop3 = (base.prop1 == 'a')

a = A('a', 'b')
b = B(a)

print(a)
print(b)
feral finchBOT
#

@hazy kiln :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | A(prop1='a', prop2='b')
002 | B(prop1='a', prop2='b', prop3=True)
hazy kiln
#

yw

feral finchBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.