• Superclass static method name from subclass

    From Ian Pilcher@21:1/5 to All on Fri Nov 11 10:21:03 2022
    Is it possible to access the name of a superclass static method, when
    defining a subclass attribute, without specifically naming the super-
    class?

    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'?

    --
    ========================================================================
    Google Where SkyNet meets Idiocracy ========================================================================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Ian Pilcher on Fri Nov 11 12:02:37 2022
    You can define a classmethod in SubClass that seems to do the job:

    class SuperClass(object):
    @staticmethod
    def spam(): # "spam" and "eggs" are a Python tradition
    print('spam from SuperClass')

    class SubClass(SuperClass):
    @classmethod
    def eggs(self):
    super().spam()

    SubClass.eggs() # Prints "spam from SuperClass"

    If you try to make it a @staticmethod, though, you would need to provide
    a class argument to super(), but a staticmethod does not pass one in.

    On 11/11/2022 11:21 AM, 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?

    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'?


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lars Liedtke@21:1/5 to All on Fri Nov 11 17:46:46 2022
    yes,

    just use SubClass.foo

    at least this works for me:

    class SuperClass:
    @staticmethod
    def test():
    print("yay")

    class SubClass(SuperClass):

    def __init__(self):
    super().__init__()
    SubClass.test()

    subclass = SubClass()

    Output:

    python3.11 test.py
    yay


    Cheers

    Lars


    Lars Liedtke
    Software Entwickler

    [Tel.] +49 721 98993-
    [Fax] +49 721 98993-
    [E-Mail] lal@solute.de<mailto:lal@solute.de>


    solute GmbH
    Zeppelinstraße 15
    76185 Karlsruhe
    Germany


    [Logo Solute]


    Marken der solute GmbH | brands of solute GmbH
    [Marken]
    [Advertising Partner]

    Geschäftsführer | Managing Director: Dr. Thilo Gans, Bernd Vermaaten
    Webseite | www.solute.de <http://www.solute.de/>
    Sitz | Registered Office: Karlsruhe
    Registergericht | Register Court: Amtsgericht Mannheim
    Registernummer | Register No.: HRB 110579
    USt-ID | VAT ID: DE234663798



    Informationen zum Datenschutz | Information about privacy policy https://www.solute.de/ger/datenschutz/grundsaetze-der-datenverarbeitung.php




    Am 11.11.22 um 17:21 schrieb Ian Pilcher:
    Is it possible to access the name of a superclass static method, when
    defining a subclass attribute, without specifically naming the super-
    class?

    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'?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dieter Maurer@21:1/5 to Ian Pilcher on Fri Nov 11 18:29:35 2022
    Ian Pilcher wrote at 2022-11-11 10:21 -0600:
    Is it possible to access the name of a superclass static method, when >defining a subclass attribute, without specifically naming the super-
    class?

    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'?

    Unless you overrode it, you can use `self.foo` or `SubClass.foo`;
    if you overrode it (and you are using either Python 3 or
    Python 2 and a so called "new style class"), you can use `super`.
    When you use `super` outside a method definition, you must
    call it with parameters.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ian Pilcher@21:1/5 to Dieter Maurer on Fri Nov 11 16:04:34 2022
    On 11/11/22 11:29, Dieter Maurer wrote:
    Ian Pilcher wrote at 2022-11-11 10:21 -0600:

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

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

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

    Unless you overrode it, you can use `self.foo` or `SubClass.foo`;
    if you overrode it (and you are using either Python 3 or
    Python 2 and a so called "new style class"), you can use `super`.
    When you use `super` outside a method definition, you must
    call it with parameters.

    SubClass.foo doesn't work, because 'SubClass' doesn't actually exist
    until the class is defined.

    class SubClass(SuperClass):
    ... bar = SubClass.foo
    ...
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in SubClass
    NameError: name 'SubClass' is not defined. Did you mean: 'SuperClass'?

    Similarly, self.foo doesn't work, because self isn't defined:

    class SubClass(SuperClass):
    ... bar = self.foo
    ...
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in SubClass
    NameError: name 'self' is not defined

    --
    ========================================================================
    Google Where SkyNet meets Idiocracy ========================================================================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ian Pilcher@21:1/5 to Thomas Passin on Fri Nov 11 16:07:08 2022
    On 11/11/22 11:02, Thomas Passin wrote:
    You can define a classmethod in SubClass that seems to do the job:

    class SuperClass(object):
          @staticmethod
          def spam():  # "spam" and "eggs" are a Python tradition
              print('spam from SuperClass')

    class SubClass(SuperClass):
        @classmethod
        def eggs(self):
            super().spam()

    SubClass.eggs()  # Prints "spam from SuperClass"


    That did it! Thanks!

    --
    ========================================================================
    Google Where SkyNet meets Idiocracy ========================================================================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cameron Simpson@21:1/5 to Cameron Simpson on Sat Nov 12 09:36:16 2022
    On 12Nov2022 09:17, Cameron Simpson <cs@cskk.id.au> wrote:
    On 11Nov2022 10:21, Ian Pilcher <arequipeno@gmail.com> wrote:
    class SubClass(SuperClass):
    bar = SuperClass.foo
    ^^^^^^^^^^

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

    I think not.

    Then I saw your "Dealing with non-callable classmethod objects" post
    which mentions `__init_subclass__`. Which feels like I've read about
    that before, but had entirely slipped my mind.

    Maybe:

    class SubClass(SuperClass):
    @classmethod
    def __init__subclass__(cls):
    cls.bar = super().foo

    would do the trick. Looks clean, but I haven't tried it yet.

    Cheers,
    Cameron Simpson <cs@cskk.id.au>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cameron Simpson@21:1/5 to Ian Pilcher on Sat Nov 12 09:17:26 2022
    On 11Nov2022 10:21, Ian Pilcher <arequipeno@gmail.com> wrote:
    Is it possible to access the name of a superclass static method, when >defining a subclass attribute, without specifically naming the super-
    class?

    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'?

    I think not.

    All the posts so far run from inside methods, which execute after you've
    got an instance of `SubClass`.

    However, during the class definition the code under `class SubClass` is
    running in a standalone namespace - not even inside a completed class.
    When that code finished, that namespace is used to create the class
    definition.

    So you have no access to the `SuperClass` part of `class
    SubClass(SuperClass):` in the class definition execution.

    Generally it is better to name where something like this comes from
    anyway, most of the time.

    However, if you really want to plain "inherit" the class attribute
    (which I can imagine valid use cases for), maybe write a property?

    @property
    def bar(self):
    return super().foo

    That would still require an instance to make use of it, so you can't
    write explicitly `SubClass.bar`.

    Possibly a metaclass would let you write a "class property", or to
    define `bar` as a class attribute directly.

    Cheers,
    Cameron Simpson <cs@cskk.id.au>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Ian Pilcher on Fri Nov 11 19:07:03 2022
    On 11/11/2022 5:07 PM, Ian Pilcher wrote:
    On 11/11/22 11:02, Thomas Passin wrote:
    You can define a classmethod in SubClass that seems to do the job:

    class SuperClass(object):
           @staticmethod
           def spam():  # "spam" and "eggs" are a Python tradition
               print('spam from SuperClass')

    class SubClass(SuperClass):
         @classmethod
         def eggs(self):
             super().spam()

    SubClass.eggs()  # Prints "spam from SuperClass"


    That did it!  Thanks!

    Glad I could help. I probably should have written

    def eggs(clas): # instead of "self"

    but it's not actually used anyway.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axy@21:1/5 to Ian Pilcher on Sun Nov 13 12:27:42 2022
    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?

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Axy via Python-list on Sat Nov 19 21:17:00 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)