How to get an attribute just from the current class and not from possible parent classes? If I use getattr
it traverses class hierarchy but I would like to get None
if attribute is not defined in the current class (even if it is defined in some parent class).

- 6,756
- 5
- 54
- 86
-
5Why are you trying to both use inheritance to define the class and not use inheritance within the class? This sounds like you've made a design mistake. Can you provide some more details? – S.Lott Jul 19 '10 at 21:30
-
Yes, it is somewhat hackish. The problem is I have to reuse existing API so I have to play ugly. But I think this is a valid question by itself. – Mitar Jul 19 '10 at 21:34
-
It's doesn't sound "hackish" -- It sounds broken. You should be using **Delegation**. Not **Inheritance**. Please provide some background in what you think you're trying to do. – S.Lott Jul 19 '10 at 23:47
-
I have published final code [on Django Trac](http://code.djangoproject.com/ticket/7018#comment:9). I made a metaclass and mixin to allow multiple ModelForm inheritance. – Mitar Jul 21 '10 at 10:34
-
I have also [posted an answer](http://stackoverflow.com/questions/2601487/django-registration-django-profile-using-your-own-custom-form/3298481#3298481) using this metaclass and mixin on Stack Overflow. – Mitar Jul 21 '10 at 11:02
3 Answers
This is not a 100% proof answer (e.g. it will not work for classes that use __slots__
), but it will work in most cases:
>>> class A(object):
... x = 42
... y = 43
...
>>> class B(A):
... x = 11
...
>>> b = B()
You can check if the attribute is defined in the class directly like this:
>>> 'x' in b.__class__.__dict__
True
>>> 'y' in b.__class__.__dict__
False
Now to answer your question:
# comment explaining why this unusual check is necessary
if 'attribute' in instance.__class__.__dict__:
value = instance.attribute
else:
value = None

- 11,010
- 4
- 41
- 39
You kind of painted yourself into a corner with your own rules. Sounds more like like a design shortcoming than a language or class issue with Python, as the beuty of python is to remove and hide the complexity of class inheritance.
You will likely need to settle for an "alternative" solution like this:
class Parent(object):
property_on_parent = 'default value'
@property
def property_accessor(self):
return self.property_on_parent
class Child(Parent):
property_on_child = None
@property
def property_accessor(self):
return self.property_on_child
c = Child()
assert c.property_accessor == None
However, i feel that you are better off rethinking the approach.

- 4,926
- 25
- 24
Nothing prevents you from "resetting" that attrib in the init setting it to None after you init the super (in Python classes inherited and inheriting are super and sub btw, not parent and child).
Unless that attrib is created elsewhere and its presence isn't guaranteed, only in that case walking up the inheritance tree, at which point you might have some serious design issues going on :)
All that said, these are poor man solutions to the problem, and I agree you might have some design issues to address instead.