Reputation: 6028
class A (object):
keywords = ('one', 'two', 'three')
class B (A):
keywords = A.keywords + ('four', 'five', 'six')
Is there any way to change A.keywords
to <thing B derives from>.keywords
, sort of like super()
, but pre-__init__/self
? I don't like repeating class names in definitions.
Usage:
>>> A.keywords
('one', 'two', 'three')
>>> B.keywords
('one', 'two', 'three', 'four', 'five', 'six')
Upvotes: 2
Views: 602
Reputation: 1
I found a workaround-style solution working for me without additional classes and defs.
class BaseModelAdmin(admin.ModelAdmin):
_readonly_fields = readonly_fields = ('created_by', 'date_add', 'date_upd', 'deleted')
and when subclassing
class PayerInline(BaseTabularInline):
exclude = BaseTabularInline._exclude + ('details',)
Hope this helps.
Upvotes: 0
Reputation: 2539
Yes. Use the __bases__ attr to find the base class(es) whenever you've already init'ed your class. Otherwise you need to change approach as B is not aware of its parents.
class A (object):
keywords = ('one', 'two', 'three')
class B (A):
def __init__(self):
keywords = self.__bases__[0].keywords + ('four', 'five', 'six')
Upvotes: 1
Reputation: 798606
Actually, you can. Write a descriptor that checks the class's bases for an attribute with the same name and add the passed attributes to its value.
class parentplus(object):
def __init__(self, name, current):
self.name = name
self.value = current
def __get__(self, instance, owner):
# Find the attribute in self.name in instance's bases
# Implementation left as an exercise for the reader
class A(object):
keywords = ('one', 'two', 'three')
class B(A):
keywords = parentplus('keywords', ('four', 'five', 'six'))
Upvotes: 5
Reputation: 649
Use metaclass :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Meta(type):
def __new__(cls, name, bases, attrs):
new_cls = super(Meta,cls).__new__(cls, name, bases, attrs)
if hasattr(new_cls, 'keywords'):
new_cls.keywords += ('1','2')
return new_cls
class B(object):
keywords = ('0',)
__metaclass__= Meta
def main():
print B().keywords
if __name__ == '__main__':
main()
Upvotes: 1