1

How can I do this (without init):

class Test(Objekt, UserMixin): 
  
    @staticmethod
    def Foo():
        return 1

    my_dict = {
        "foo_val": Test.Foo(),
    } 

I tried:

    my_dict = {
        "foo_val": lambda: Test.Foo(),
    } 

But of course the lamda function is stored, not its result!

(this example is simplified)

4 Answers 4

1

You have a few alternatives here:

call the function before decorating it with staticmethod:

class Test(Objekt, UserMixin): 
  
    def Foo():
        return 1

    my_dict = {
        "foo_val": Foo(),
    }

    Foo = staticmethod(Foo)

Or, add it to the dictionary outside the class statement:

class Test(Objekt, UserMixin): 

    my_dict = {}

    @staticmethod
    def Foo():
        return 1

Test.my_dict["foo_val"] = Test.Foo()

Finally, use the __func__ attribute of the staticmethod object:

class Test(Objekt, UserMixin): 
  
    @staticmethod
    def Foo():
        return 1

    my_dict = {
        "foo_val": Foo.__func__(),
    } 

Not sure which of these three approaches is the cleanest, to be frank.

Sign up to request clarification or add additional context in comments.

Comments

1

You can declare my_dict as property

@property
def my_dict(self):
    return {"foo_val": Test.Foo()}

Comments

0

One way could be to declare my_dict as a class property (or a normal instance property, if that's okay for your use case, that would save you from using the classproperty class).

class classproperty(property):
    def __get__(self, cls, owner):
        return self.fget.__get__(owner)()

class Test():

    @staticmethod
    def Foo():
        return 1

    @classproperty
    def my_dict(cls):
        return {
            "foo_val": cls.Foo(),
        }

print(Test.my_dict)

Output:

{'foo_val': 1}

Using a normal property:

class Test():

    @staticmethod
    def Foo():
        return 1

    @property
    def my_dict(cls):
        return {
            "foo_val": cls.Foo(),
        }

print(Test().my_dict) # notice that this requires to create an instance!

Another way could be to

  1. use a metaclass

  2. fill my_dict after the class definition

2 Comments

What's the point of using classmethod here? why not just: return self.fget.__get__(owner)()?
@juanpa.arrivillaga good point, I'll update my answer.
0

Thanks to all! Just for completion. Another solution could be:

class Test(Objekt, UserMixin): 
  
    @staticmethod
    def Foo():
        return Test.my_dict["foo_val"]

    my_dict = {
        "foo_val": 1,
    } 

As mentioned, this is a special case and the "foo_val" entry has to be item of that dict! Thus I think this is a valid solution here. Otherwise I wold prefer one og the other solutions mentioned in this thread

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.