0

Is there a way that in a class methods I can use an instance variable to perform a calculation?

Very simplified, this is what I am attempting to do:

class Test:

  def __init__(self, a):
    self.a = a

  @classmethod
  def calculate(cls, b):
     return self.a + b
5
  • 5
    There is no self in a class method. Your method would work perfectly fine as a normal instance method. Why push square peg in a round hole? i.e. why do you think you should have a class method, if you are doing calculations on an instance? Your "very simplified" might have been too simplified to understand - all I see is wrong code easily fixable by removing @classmethod and replacing cls with self. Commented Feb 19, 2019 at 0:20
  • 2
    The .a of which instance should be used in that method? You don't have a preferred self instance, but you could pass an instance (or multiple instances) as explicit parameter to the class function if you really need to. Commented Feb 19, 2019 at 0:22
  • The descriptor protocol explicitly allows this; the dot operator will access the __get__ method of a descriptor with both the instance and the class. See docs.python.org/3/howto/descriptor.html#functions-and-methods. Commented Feb 19, 2019 at 0:32
  • Possible duplicate of Creating a method that is simultaneously an instance and class method Commented Feb 19, 2019 at 0:33
  • @Amadan my original problem is something along the lines of instantiating a filename in the init of the class, then using that filename in a classmethod to lazily get a pandas dataframe that will be available for all object instances once opened (to save memory) Commented Feb 19, 2019 at 1:44

2 Answers 2

1

all I want is to declare a variable 'a', then use it in a class method for calculation purposes.

If you want to cache a class-wide value, these are your basic options:

Set value explicitly:

class Foo:
    @classmethod
    def set_foo(cls):
        print('Setting foo')
        cls.foo = 'bar'

    def print_foo(self):
        print(self.__class__.foo)

Foo.set_foo()      # => 'Setting foo'
Foo()
Foo().print_foo()  # => 'bar'

Set value at class init:

class Foo:
    print('Setting foo')
    foo = 'bar'

    def print_foo(self):
        print(self.__class__.foo)
# => 'Setting foo'

Foo()
Foo()
Foo().print_foo()  # => 'bar'

Set value at first instance init:

class Foo:
    def __init__(self):
        if not hasattr(self.__class__, 'foo'):
            print('Setting foo')
            self.__class__.foo = 'bar'

    def print_foo(self):
        print(self.__class__.foo)

Foo()              # => 'Setting foo'
Foo()
Foo().print_foo()  # => 'bar'
Sign up to request clarification or add additional context in comments.

Comments

0

If you want the namespacing use @staticmethod instead and let users pass in the variables e.g. Test.calculate(a, b)

1 Comment

I think my question might've been missunderstood, but all I want is to declare a variable 'a', then use it in a class method for calculation purposes. I think that in my init I should just do Test.a = a.

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.