2

In python 2.7, I want to create a static variable which stores the result of running a static method of the enclosing class.

I tried the following:

class A:
    @staticmethod
    def foo():
            return 1
    v = A.foo() # a static variable
print A.v

which returns the error:

NameError: name 'A' is not defined

However, referring to another class' static variable works:

class B:
    @staticmethod
    def foo():
            return 1
class A:
    @staticmethod
    def foo():
            return 1
    v = B.foo()

print A.v

>>> 1

Any explanations?

EDIT:

The use-case for this scenario is caching the result of foo, and enclose it under A's name space. Following the answers I understand that A is not yet defined at the execution time, which leads to an error. I came up with the following to delay the computation:

class A:
    @staticmethod
    def foo():
            print 'running foo'
            return 1

    @staticmethod
    def get_v():
            try:
                    return A.v
            except AttributeError:
                    A.v = A.foo()
                    return A.v

print A.get_v()
print A.get_v()

>>> running foo
>>> 1
>>> 1

This seems to do the job, but is somewhat cumbersome.

5
  • 2
    At that time A doesn't even exist, hence the error. Commented Mar 8, 2016 at 9:18
  • Can you explain why you would want to do this? Is it just for caching purposes? Commented Mar 8, 2016 at 9:27
  • In this example you would want to move foo() outside of the class and make it a function, but I suspect you want to do something more complicated. Commented Mar 8, 2016 at 9:28
  • Yep, would like to run the function once, and use its return value from multiple instances of A. Commented Mar 8, 2016 at 9:28
  • @DanielRoseman edited the question with use-case and possible yet cumbersome solution. Commented Mar 8, 2016 at 9:44

3 Answers 3

3

Use @classmethod, and cache the value on the class object.

class S(object):
    @classmethod
    def f(klass):
        if not hasattr(klass, '_f'):
            print "Calculating value"
            klass._f = 5

        return klass._f

When called twice from different instances:

>>> s = S()
>>> s2 = S()
>>> s.f()
Calculating value
5
>>> s2.f()
5

The value is shared over all instances of S.

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

Comments

1

Apart from wondering why you're doing this: at the time you assign v (in the line v = A.foo(), A has not been defined yet. (The definition of A is the entire class block, so A isn't defined until after that block.)

In your second example, B is already defined when you say v = B.foo().

EDIT: What puzzles me is the following:

class A:
    @staticmethod
    def foo():
        return 1
    v = foo()

Running this code results in

    v = foo()
TypeError: 'staticmethod' object is not callable

5 Comments

I'd like to cache the return value of foo to run it only once, and share across users of A. Can you offer another way to go?
Move the function to before A's definition, and within A, set v = foo().
Alternatively, if you want to keep the function within A (as a static method), after A's full definition, write A.v = A.foo().
That would work, but then foo would be out of A's namespace, which is less convenient for me. I edited the question with another possible option.
your second option would require that i'll be aware of the first execution of foo.
1

You cannot call a (static) method from class A until the class is fully defined (end of block class). But you can define a static variable as soon as the class is defined:

class A:
    @staticmethod
    def foo():
        print "running foo"
        return 1
A.v = A.foo()

You can then use anywhere

print A.v

2 Comments

Do you know why you cannot call foo until A is fully defined? If class A: ; foo=lambda:1 ; v=foo() is allowed, why not def foo(): return 1 instead of foo=lambda: 1?
@acdr In your example you assign to static variables, assign an external function to a variable and call the external function through the static variable. It is the same as def foo(): ; return 1; class A: f = foo; v = f(). But a static method belongs to a class and cannot be executed before the class is fully defined.

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.