python - Can you make a class variable that calls an instance of the class? - Stack Overflow

admin2025-04-28  4

I am working with a class which does some math and stores the result, and then a line that sets a "noresult" to that class but initiated with zeroes, like so (I'm leaving out the math, this should be all the relevant bits):

class Result(object):
  def __init__(self, slope, offset):
    self._slope = slope
    self._offset = offset
  
  @classmethod
  def dothemath(cls, etc):
    ...


Result.NORESULT = Result((0, 0), (0, 0))

Then there's a lot of places where it sets an object's "result" attribute to an instance of this class and later says things like "if object.result is not Result.NORESULT"

This works fine, but PyCharm highlights it everywhere it's used by importing the class, complaining that the class has no attribute NORESULT. Is there any way to get the exact same functionality into the definition of the class itself (i.e., calling the class while not needing to initialize it?)

I had two ideas, but neither works:

class Result(object):
  NORESULT = cls((0,0), (0,0))
  
  def __init__:
    ...


class Result(object):
  def __init__(self, slope, offset):
    self.NORESULT = cls((0, 0), (0, 0))
    ...

both give me "Unresolved reference cls", so I guess that doesn't work - and anyway, the second one would require me to initialize the class to get NORESULT instead. I've definitely seen cls() used before in this code so I'm not sure why it works in some places and not others. Is this kind of recursiveness actually something that can be put in the class?

I'm aware Python 2.7 is no longer supported, although it's not part of the snippet of code this particular question is about, I am working with Gwyddion which has no plans to update its Python integration package, gwy, from 2.7 to 3.x.

I am working with a class which does some math and stores the result, and then a line that sets a "noresult" to that class but initiated with zeroes, like so (I'm leaving out the math, this should be all the relevant bits):

class Result(object):
  def __init__(self, slope, offset):
    self._slope = slope
    self._offset = offset
  
  @classmethod
  def dothemath(cls, etc):
    ...


Result.NORESULT = Result((0, 0), (0, 0))

Then there's a lot of places where it sets an object's "result" attribute to an instance of this class and later says things like "if object.result is not Result.NORESULT"

This works fine, but PyCharm highlights it everywhere it's used by importing the class, complaining that the class has no attribute NORESULT. Is there any way to get the exact same functionality into the definition of the class itself (i.e., calling the class while not needing to initialize it?)

I had two ideas, but neither works:

class Result(object):
  NORESULT = cls((0,0), (0,0))
  
  def __init__:
    ...


class Result(object):
  def __init__(self, slope, offset):
    self.NORESULT = cls((0, 0), (0, 0))
    ...

both give me "Unresolved reference cls", so I guess that doesn't work - and anyway, the second one would require me to initialize the class to get NORESULT instead. I've definitely seen cls() used before in this code so I'm not sure why it works in some places and not others. Is this kind of recursiveness actually something that can be put in the class?

I'm aware Python 2.7 is no longer supported, although it's not part of the snippet of code this particular question is about, I am working with Gwyddion which has no plans to update its Python integration package, gwy, from 2.7 to 3.x.

Share Improve this question edited Jan 9 at 18:04 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Jan 9 at 17:57 RékaRéka 1458 bronze badges 3
  • cls only works where that name is in scope, as it is in a method where it's the name of the first parameter. It's not a global, or anything magical, just a convention for class method parameter naming. – jonrsharpe Commented Jan 9 at 18:06
  • @jonsharpe how and why did you just edit my post what the hell. I don't really appreciate that, just tell me what I should change instead of changing my wording... – Réka Commented Jan 9 at 18:07
  • stackoverflow.com/help/editing – jonrsharpe Commented Jan 9 at 18:09
Add a comment  | 

1 Answer 1

Reset to default 0

Declare the class attribute with a default value, then re-assign it later.

class Result(object):
  NORESULT = None

  def __init__(self, slope, offset):
    self._slope = slope
    self._offset = offset
  
  @classmethod
  def dothemath(cls, etc):
    ...


Result.NORESULT = Result((0, 0), (0, 0))
转载请注明原文地址:http://anycun.com/QandA/1745782390a91221.html