Reputation: 1106
Doing so suits my needs but I wonder if it's considered blasphemous (or, even, un-pythonic).
Example:
class A:
_class_specific = 1
def __init__(self, i):
self.instance_specific = i
def get_special_sum(self):
return self._class_specific + self.instance_specific
t = A(2)
t.get_special_sum() #< Returns 3
Reason for doing so:
I have a class variable _ID
and an instance method check(self)
defined in a Base class. Child classes have their own values for _ID
. The inherited check(self)
method must have access to instance-specific variables as well as the _ID
variable of a given genus, which it will access through self._ID
Although the above works perfectly I wonder if there is a more explicit way of doing it? ...other than leaving a glaringly obvious comment making clear what the intention is...
Upvotes: 0
Views: 110
Reputation: 33107
"Bad practice" is subjective, but one thing's for sure, you can more explicitly access a class variable via type(self)
or self.__class__
, for example:
def get_special_sum(self):
return type(self)._class_specific + self.instance_specific
So you might prefer to lookup on self
in cases where the variable might be defined on the instance, otherwise it's defined on the class. Maybe that's even the case you've described — you'd be the best judge of that.
As for type(self)
vs self.__class__
, see Difference between type(obj) and obj.__class__
Upvotes: 1
Reputation: 110516
No, there is no problem -
And it even adds flexibility to your project: say, you want one specific instance of your class to have a different value for that variable, all you have to do is set it on the instance. Just add some unit tests to ensure everywhere it is used it is being read from self.
, and there is no drawback.
And, yes (following some of the comments on the O.P.), if you prefer to be explicit about only allowing the value to be fectched from the class, and never be set on the instance, you can do self.__class__.attribute
or type(self).attribute
: it is mostly a matter of taste. If self.__class__
is to be used more than once inside a method, consider assigning it to a variable in the beggining of the method: you can a lot of legibility (and even some micro optimizations): cls = self.__class__
That said, I had used the pattern of reading class values from self
and using some instances with specific values, and it really feels natural, and "the right way to do it". Just take care when setting the attribute instead: self.attr = X
will always set the attribute in a single instance. When setting you have to be explicit about setting it on the class!
Upvotes: 2