On 11/13/2022 7:27 AM, Axy via Python-list wrote:
On 11/11/2022 16:21, Ian Pilcher wrote:
Is it possible to access the name of a superclass static method, when
defining a subclass attribute, without specifically naming the super-
class?

A instance's __bases__ attribute is a sequence that contains all its base classes. So:

class A:
    @staticmethod
    def double(n):
        return 2 * n

class B(A):
    def parent_method(self, n):
        par = self.__class__.__bases__[0]  # For single inheritance
        return par.double(n)

b = B()
print(b.parent_method(3))  # 6

#  or
print(b.__class__.__bases__[0].double(4)) # 8


Contrived example:

  class SuperClass(object):
      @staticmethod
      def foo():
          pass

  class SubClass(SuperClass):
      bar = SuperClass.foo
            ^^^^^^^^^^

Is there a way to do this without specifically naming 'SuperClass'?

There is, but it's weird. I constructed classes from yaml config so I did not even know the name of super class but I wanted similar things for my clabate templates and I implemented superattr() which works for me:

class BasePage:

     body = '<p>Hello</p>'

class MySpecificPage(BasePage):

     body = superattr() + '<p>World<p/>'

Actually, it's suboptimally elegant code. Artistic code, to be clear, as if you looked at modern art and thought: WTF? Also, it's specific for templates only and supports only __add__.

But I think the approach can be extended to a general superclass() if you log __getattr__ calls and apply them in __get__ method same way.

I realize this reply is not an immediate help and probably won't help, but there's always a way out.

Axy.

Here's the code:


class  superattr:
     '''
This is a descriptor that allows extending attributes in a simple and elegant way:

my_attr = superattr() + some_addition_to_my_attr
'''
     def  __init__(self):
         self.additions  =  []

     def  __set_name__(self,  owner,  name):
         print('__set_name__',  name)
         self.attr_name  =  name

     def  __get__(self,  obj,  objtype=None):
         for  cls  in  obj.__class__.__mro__[1:]:
             try:
                 value  =  getattr(cls,  self.attr_name)
             except  AttributeError:
                 continue
             for  a  in  self.additions:
                 value  =  value  +  a
             return  value
         raise  AttributeError(self.attr_name)

     def  __add__(self,  other):
         print('__add__:',  other)
         self.additions.append(other)
        return  self Full article: https://declassed.art/en/blog/2022/07/02/a-note-on-multiple-inheritance-in-python

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to