6

There are plenty answers for how to access static variables from static methods (like this one, and that one, and the great info on the subject here), however I'm having trouble with the other direction: How can you use static methods to initialize static variables. E.g.:

import os, platform
class A(object):
 @staticmethod
 def getRoot():
 return 'C:\\' if platform.system() == 'Windows' else '/'
 pth = os.path.join(A.getRoot(), 'some', 'path')

The last line gives an exception: NameError: name 'A' is not defined. The same error happens if I use @classmethod instead of @staticmethod.

Is it possible to access a static method from a class variable?

asked May 11, 2015 at 15:16
1
  • Write the line outside of the method. Commented May 11, 2015 at 15:18

3 Answers 3

5

The problem is that the class "A" doesn't exist yet at the moment your variable path is declared, so the evaluation fails. How about declaring it right after?

import os, platform
class A(object):
 @staticmethod
 def getRoot():
 return 'C:\\' if platform.system() == 'Windows' else '/'
A.pth = os.path.join(A.getRoot(), 'some', 'path')

An uglier alternative would be:

import os, platform
class A(object):
 @staticmethod
 def getRoot():
 return 'C:\\' if platform.system() == 'Windows' else '/'
 pth = os.path.join(getRoot.__func__(), 'some', 'path')

... but it's pretty unreadable (and depends on implementation details of @staticmethod, which is bad).

For this specific case I'd do something like this (which doesn't really answer your question, instead it sidesteps the need for it):

import os, platform
class A(object):
 _root = 'C:\\' if platform.system() == 'Windows' else '/'
 @staticmethod
 def getRoot():
 return A._root
 pth = os.path.join(_root, 'some', 'path')

... because your platform is pretty unlikely to change while your program is still running, right? :) If you have a better reason to do something like that, maybe use one of the methods above.

answered May 11, 2015 at 15:18

Comments

1

You can defer the evaluation of pth by using a classproperty:

class A(object):
 @staticmethod
 def getRoot():
 return 'C:\\' if platform.system() == 'Windows' else '/'
 @classproperty
 def pth(cls):
 return os.path.join(cls.getRoot(), 'some', 'path')

classproperty is not a builtin, but it is a widely used recipe.

As a side note, IMHO, you should always prefer using classmethod over staticmethod.

answered May 11, 2015 at 15:49

Comments

-1

What I did in the end was have A extend a different class B which has the staticmethod I wanted. I.e.:

import os
import platform
class B(object):
 @staticmethod
 def getRoot():
 return r'C:\\' if platform.system() == 'Windows' else '/'
class A(B):
 pth = os.path.join(B.getRoot(), 'some', 'path')

Although this is what worked best for me it is more a work around rather than an answer.

answered May 12, 2015 at 5:53

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.