0

Sometimes in __init__ I already have the instance that self is supposed to become, and I simply want to set it to that.
The simplest case is that the argument used to initialize a Foo is itself a Foo.
(Foo(Foo(x)) == Foo(x) just like set({1, 2}) == {1, 2}.)
In the example this is case_trivial. But there is also case_variadic.

Currently I have to set each attribute on its own. Is there a way to do that in one line?

from variadic_foo_operations import foo_addition, foo_multiplication


class Foo(object):

    def __init__(self, arg=None, addends=None, factors=None):

        case_arg = arg is not None
        case_normal = case_arg and type(arg) == int
        case_trivial = case_arg and type(arg) == Foo

        case_add = addends is not None
        case_multiply = factors is not None
        case_variadic = case_add or case_multiply

        if case_normal:
            self.bar = arg
            self.double_bar = 2 * arg
        elif case_trivial:
            the_foo_i_want = arg
        elif case_variadic:
            operation = foo_addition if case_add else foo_multiplication
            operands = addends if case_add else factors
            current_foo = Foo(0) if case_add else Foo(1)  # neutral element
            for operand_foo in operands:
                current_foo = operation(current_foo, operand_foo)
            the_foo_i_want = current_foo

        if case_trivial or case_variadic:
            # What I would like:
            self = the_foo_i_want
            # What I have to do instead:
            self.bar = the_foo_i_want.bar
            self.double_bar = the_foo_i_want.double_bar
3
  • 1
    No, by the time __init__ gets called Python has already created the new instance - self is just a method parameter at that point, assigning to it doesn't have any impact outside the method. Maybe you want to override __new__ instead? Commented Jul 19, 2020 at 14:55
  • It sounds like you want a copy constructor, but Python doesn't provide anything similar out of the box. As a note, I think this method does too much disparate work. I'd suggest leaving just initialisation in your __init__ and introducing auxiliary functions that implement the calculation. So you'd have something like def new_foo_add(addends): ...; return Foo(bar=..., ...). Also, type(arg) == Foo is going to break if you ever inherit from Foo. Commented Jul 19, 2020 at 15:07
  • @Norrius If addends is one one of the ways to initialize Foo, then __init__ is the place where I have it. How would you get it to that auxiliary function? Commented Jul 19, 2020 at 19:16

1 Answer 1

0

Found the answer here: How to copy all properties of an object to another object

self.__dict__ = the_foo_i_want.__dict__.copy()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.