How to refer to subclasses in the superclass?











up vote
-2
down vote

favorite












I am defining a Python Holiday class and three subclasses: one for fixed date holidays, a second for relative holidays, and a third for floating Monday holidays. I would like to create a set of constants in the superclass Holiday so that applications can simply refer to particular holidays as



Holiday.NEW_YEARS
Holiday.CHRISTMAS
etc.


but the subclasses obviously do not exist when the parent class is instantiated. How can I do this?



class Holiday(object):
NEW_YEARS = FixedHoliday(1, 1)
MLK_BIRTHDAY = FloatingMonday(1, 15)
...









share|improve this question
























  • Possible duplicate of stackoverflow.com/questions/576169/…
    – quant
    Nov 10 at 22:05










  • You probably need another parent class that Holiday can inherent the constants from.
    – Red Cricket
    Nov 10 at 22:06






  • 2




    This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
    – Jim Stewart
    Nov 10 at 22:06










  • I don't think it's a dupe of that because I'm not sure the requirement makes sense
    – roganjosh
    Nov 10 at 22:07










  • @Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
    – martineau
    Nov 10 at 23:46

















up vote
-2
down vote

favorite












I am defining a Python Holiday class and three subclasses: one for fixed date holidays, a second for relative holidays, and a third for floating Monday holidays. I would like to create a set of constants in the superclass Holiday so that applications can simply refer to particular holidays as



Holiday.NEW_YEARS
Holiday.CHRISTMAS
etc.


but the subclasses obviously do not exist when the parent class is instantiated. How can I do this?



class Holiday(object):
NEW_YEARS = FixedHoliday(1, 1)
MLK_BIRTHDAY = FloatingMonday(1, 15)
...









share|improve this question
























  • Possible duplicate of stackoverflow.com/questions/576169/…
    – quant
    Nov 10 at 22:05










  • You probably need another parent class that Holiday can inherent the constants from.
    – Red Cricket
    Nov 10 at 22:06






  • 2




    This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
    – Jim Stewart
    Nov 10 at 22:06










  • I don't think it's a dupe of that because I'm not sure the requirement makes sense
    – roganjosh
    Nov 10 at 22:07










  • @Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
    – martineau
    Nov 10 at 23:46















up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











I am defining a Python Holiday class and three subclasses: one for fixed date holidays, a second for relative holidays, and a third for floating Monday holidays. I would like to create a set of constants in the superclass Holiday so that applications can simply refer to particular holidays as



Holiday.NEW_YEARS
Holiday.CHRISTMAS
etc.


but the subclasses obviously do not exist when the parent class is instantiated. How can I do this?



class Holiday(object):
NEW_YEARS = FixedHoliday(1, 1)
MLK_BIRTHDAY = FloatingMonday(1, 15)
...









share|improve this question















I am defining a Python Holiday class and three subclasses: one for fixed date holidays, a second for relative holidays, and a third for floating Monday holidays. I would like to create a set of constants in the superclass Holiday so that applications can simply refer to particular holidays as



Holiday.NEW_YEARS
Holiday.CHRISTMAS
etc.


but the subclasses obviously do not exist when the parent class is instantiated. How can I do this?



class Holiday(object):
NEW_YEARS = FixedHoliday(1, 1)
MLK_BIRTHDAY = FloatingMonday(1, 15)
...






python






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 23:05









martineau

64.8k887175




64.8k887175










asked Nov 10 at 22:03









philhanna

123




123












  • Possible duplicate of stackoverflow.com/questions/576169/…
    – quant
    Nov 10 at 22:05










  • You probably need another parent class that Holiday can inherent the constants from.
    – Red Cricket
    Nov 10 at 22:06






  • 2




    This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
    – Jim Stewart
    Nov 10 at 22:06










  • I don't think it's a dupe of that because I'm not sure the requirement makes sense
    – roganjosh
    Nov 10 at 22:07










  • @Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
    – martineau
    Nov 10 at 23:46




















  • Possible duplicate of stackoverflow.com/questions/576169/…
    – quant
    Nov 10 at 22:05










  • You probably need another parent class that Holiday can inherent the constants from.
    – Red Cricket
    Nov 10 at 22:06






  • 2




    This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
    – Jim Stewart
    Nov 10 at 22:06










  • I don't think it's a dupe of that because I'm not sure the requirement makes sense
    – roganjosh
    Nov 10 at 22:07










  • @Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
    – martineau
    Nov 10 at 23:46


















Possible duplicate of stackoverflow.com/questions/576169/…
– quant
Nov 10 at 22:05




Possible duplicate of stackoverflow.com/questions/576169/…
– quant
Nov 10 at 22:05












You probably need another parent class that Holiday can inherent the constants from.
– Red Cricket
Nov 10 at 22:06




You probably need another parent class that Holiday can inherent the constants from.
– Red Cricket
Nov 10 at 22:06




2




2




This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
– Jim Stewart
Nov 10 at 22:06




This isn't good OO. A superclass shouldn't know about or interact with its descendants. If you want to do something similar, create a registry or factory, that doesn't derive from Holiday, but knows how to make one.
– Jim Stewart
Nov 10 at 22:06












I don't think it's a dupe of that because I'm not sure the requirement makes sense
– roganjosh
Nov 10 at 22:07




I don't think it's a dupe of that because I'm not sure the requirement makes sense
– roganjosh
Nov 10 at 22:07












@Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
– martineau
Nov 10 at 23:46






@Jim Stewart: While generally I agree, in this case the OP is effectively just using the base class as a namespace (i.e. a container)—so I think what they want to do would be an exception to that rule-of-thumb, or at least falls into a grey area...
– martineau
Nov 10 at 23:46














2 Answers
2






active

oldest

votes

















up vote
0
down vote













A class can't and shouldn't refer to its derived classes. Try this instead:



class BaseHoliday(object):
pass

class FixedHoliday(BaseHoliday):
# class code

# more classes

class Holidays(object):
NEW_YEARS = FixedHoliday(1, 1)
MLK_BIRTHDAY = FloatingMonday(1, 15)





share|improve this answer





















  • I don't understand this code at all. Why are you using global naming conventions in a base class?
    – roganjosh
    Nov 10 at 22:11










  • What do you mean by "global naming conventions"?
    – roeen30
    Nov 10 at 22:14






  • 1




    Capitalisation implies global variables by PEP8
    – roganjosh
    Nov 10 at 22:15






  • 1




    Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
    – roeen30
    Nov 10 at 22:19










  • So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
    – roeen30
    Nov 10 at 22:52


















up vote
0
down vote













One way to do it would be to decorate the base class after it and all the subclasses are defined. You can this in Python because classes are mutable objects.



Here's what I'm suggesting:



class Holiday:
def __init__(self, month, day):
self.month, self.day = month, day

def __repr__(self):
return '{}(month={}, day={})'.format(type(self).__name__, self.month, self.day)

class FixedHoliday(Holiday):
pass

class FloatingMonday(Holiday):
pass

#class MondayHoliday(Holiday): ... etc


# Base class decorator.
def inject_constants(cls):
""" Add attributes to class. """
HOLIDATA = {
'NEW_YEARS': FixedHoliday(1, 1),
'MLK_BIRTHDAY': FloatingMonday(1, 15)
}

for key, value in HOLIDATA.items():
setattr(cls, key, value)


inject_constants(Holiday)

print(Holiday.NEW_YEARS) # -> FixedHoliday(month=1, day=1)
print(Holiday.MLK_BIRTHDAY) # -> FloatingMonday(month=1, day=15)





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243867%2fhow-to-refer-to-subclasses-in-the-superclass%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    A class can't and shouldn't refer to its derived classes. Try this instead:



    class BaseHoliday(object):
    pass

    class FixedHoliday(BaseHoliday):
    # class code

    # more classes

    class Holidays(object):
    NEW_YEARS = FixedHoliday(1, 1)
    MLK_BIRTHDAY = FloatingMonday(1, 15)





    share|improve this answer





















    • I don't understand this code at all. Why are you using global naming conventions in a base class?
      – roganjosh
      Nov 10 at 22:11










    • What do you mean by "global naming conventions"?
      – roeen30
      Nov 10 at 22:14






    • 1




      Capitalisation implies global variables by PEP8
      – roganjosh
      Nov 10 at 22:15






    • 1




      Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
      – roeen30
      Nov 10 at 22:19










    • So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
      – roeen30
      Nov 10 at 22:52















    up vote
    0
    down vote













    A class can't and shouldn't refer to its derived classes. Try this instead:



    class BaseHoliday(object):
    pass

    class FixedHoliday(BaseHoliday):
    # class code

    # more classes

    class Holidays(object):
    NEW_YEARS = FixedHoliday(1, 1)
    MLK_BIRTHDAY = FloatingMonday(1, 15)





    share|improve this answer





















    • I don't understand this code at all. Why are you using global naming conventions in a base class?
      – roganjosh
      Nov 10 at 22:11










    • What do you mean by "global naming conventions"?
      – roeen30
      Nov 10 at 22:14






    • 1




      Capitalisation implies global variables by PEP8
      – roganjosh
      Nov 10 at 22:15






    • 1




      Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
      – roeen30
      Nov 10 at 22:19










    • So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
      – roeen30
      Nov 10 at 22:52













    up vote
    0
    down vote










    up vote
    0
    down vote









    A class can't and shouldn't refer to its derived classes. Try this instead:



    class BaseHoliday(object):
    pass

    class FixedHoliday(BaseHoliday):
    # class code

    # more classes

    class Holidays(object):
    NEW_YEARS = FixedHoliday(1, 1)
    MLK_BIRTHDAY = FloatingMonday(1, 15)





    share|improve this answer












    A class can't and shouldn't refer to its derived classes. Try this instead:



    class BaseHoliday(object):
    pass

    class FixedHoliday(BaseHoliday):
    # class code

    # more classes

    class Holidays(object):
    NEW_YEARS = FixedHoliday(1, 1)
    MLK_BIRTHDAY = FloatingMonday(1, 15)






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 10 at 22:07









    roeen30

    43629




    43629












    • I don't understand this code at all. Why are you using global naming conventions in a base class?
      – roganjosh
      Nov 10 at 22:11










    • What do you mean by "global naming conventions"?
      – roeen30
      Nov 10 at 22:14






    • 1




      Capitalisation implies global variables by PEP8
      – roganjosh
      Nov 10 at 22:15






    • 1




      Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
      – roeen30
      Nov 10 at 22:19










    • So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
      – roeen30
      Nov 10 at 22:52


















    • I don't understand this code at all. Why are you using global naming conventions in a base class?
      – roganjosh
      Nov 10 at 22:11










    • What do you mean by "global naming conventions"?
      – roeen30
      Nov 10 at 22:14






    • 1




      Capitalisation implies global variables by PEP8
      – roganjosh
      Nov 10 at 22:15






    • 1




      Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
      – roeen30
      Nov 10 at 22:19










    • So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
      – roeen30
      Nov 10 at 22:52
















    I don't understand this code at all. Why are you using global naming conventions in a base class?
    – roganjosh
    Nov 10 at 22:11




    I don't understand this code at all. Why are you using global naming conventions in a base class?
    – roganjosh
    Nov 10 at 22:11












    What do you mean by "global naming conventions"?
    – roeen30
    Nov 10 at 22:14




    What do you mean by "global naming conventions"?
    – roeen30
    Nov 10 at 22:14




    1




    1




    Capitalisation implies global variables by PEP8
    – roganjosh
    Nov 10 at 22:15




    Capitalisation implies global variables by PEP8
    – roganjosh
    Nov 10 at 22:15




    1




    1




    Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
    – roeen30
    Nov 10 at 22:19




    Source for this? Class names are always camelcase and begin with a capital in PEP8, see here. This is not a PEP8 discussion, however.
    – roeen30
    Nov 10 at 22:19












    So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
    – roeen30
    Nov 10 at 22:52




    So you were talking about the class attributes. You didn't mention that. I just copied that from OP. Anyway, again, this discussion is completely unconstructive and off topic.
    – roeen30
    Nov 10 at 22:52












    up vote
    0
    down vote













    One way to do it would be to decorate the base class after it and all the subclasses are defined. You can this in Python because classes are mutable objects.



    Here's what I'm suggesting:



    class Holiday:
    def __init__(self, month, day):
    self.month, self.day = month, day

    def __repr__(self):
    return '{}(month={}, day={})'.format(type(self).__name__, self.month, self.day)

    class FixedHoliday(Holiday):
    pass

    class FloatingMonday(Holiday):
    pass

    #class MondayHoliday(Holiday): ... etc


    # Base class decorator.
    def inject_constants(cls):
    """ Add attributes to class. """
    HOLIDATA = {
    'NEW_YEARS': FixedHoliday(1, 1),
    'MLK_BIRTHDAY': FloatingMonday(1, 15)
    }

    for key, value in HOLIDATA.items():
    setattr(cls, key, value)


    inject_constants(Holiday)

    print(Holiday.NEW_YEARS) # -> FixedHoliday(month=1, day=1)
    print(Holiday.MLK_BIRTHDAY) # -> FloatingMonday(month=1, day=15)





    share|improve this answer



























      up vote
      0
      down vote













      One way to do it would be to decorate the base class after it and all the subclasses are defined. You can this in Python because classes are mutable objects.



      Here's what I'm suggesting:



      class Holiday:
      def __init__(self, month, day):
      self.month, self.day = month, day

      def __repr__(self):
      return '{}(month={}, day={})'.format(type(self).__name__, self.month, self.day)

      class FixedHoliday(Holiday):
      pass

      class FloatingMonday(Holiday):
      pass

      #class MondayHoliday(Holiday): ... etc


      # Base class decorator.
      def inject_constants(cls):
      """ Add attributes to class. """
      HOLIDATA = {
      'NEW_YEARS': FixedHoliday(1, 1),
      'MLK_BIRTHDAY': FloatingMonday(1, 15)
      }

      for key, value in HOLIDATA.items():
      setattr(cls, key, value)


      inject_constants(Holiday)

      print(Holiday.NEW_YEARS) # -> FixedHoliday(month=1, day=1)
      print(Holiday.MLK_BIRTHDAY) # -> FloatingMonday(month=1, day=15)





      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        One way to do it would be to decorate the base class after it and all the subclasses are defined. You can this in Python because classes are mutable objects.



        Here's what I'm suggesting:



        class Holiday:
        def __init__(self, month, day):
        self.month, self.day = month, day

        def __repr__(self):
        return '{}(month={}, day={})'.format(type(self).__name__, self.month, self.day)

        class FixedHoliday(Holiday):
        pass

        class FloatingMonday(Holiday):
        pass

        #class MondayHoliday(Holiday): ... etc


        # Base class decorator.
        def inject_constants(cls):
        """ Add attributes to class. """
        HOLIDATA = {
        'NEW_YEARS': FixedHoliday(1, 1),
        'MLK_BIRTHDAY': FloatingMonday(1, 15)
        }

        for key, value in HOLIDATA.items():
        setattr(cls, key, value)


        inject_constants(Holiday)

        print(Holiday.NEW_YEARS) # -> FixedHoliday(month=1, day=1)
        print(Holiday.MLK_BIRTHDAY) # -> FloatingMonday(month=1, day=15)





        share|improve this answer














        One way to do it would be to decorate the base class after it and all the subclasses are defined. You can this in Python because classes are mutable objects.



        Here's what I'm suggesting:



        class Holiday:
        def __init__(self, month, day):
        self.month, self.day = month, day

        def __repr__(self):
        return '{}(month={}, day={})'.format(type(self).__name__, self.month, self.day)

        class FixedHoliday(Holiday):
        pass

        class FloatingMonday(Holiday):
        pass

        #class MondayHoliday(Holiday): ... etc


        # Base class decorator.
        def inject_constants(cls):
        """ Add attributes to class. """
        HOLIDATA = {
        'NEW_YEARS': FixedHoliday(1, 1),
        'MLK_BIRTHDAY': FloatingMonday(1, 15)
        }

        for key, value in HOLIDATA.items():
        setattr(cls, key, value)


        inject_constants(Holiday)

        print(Holiday.NEW_YEARS) # -> FixedHoliday(month=1, day=1)
        print(Holiday.MLK_BIRTHDAY) # -> FloatingMonday(month=1, day=15)






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 10 at 23:52

























        answered Nov 10 at 23:38









        martineau

        64.8k887175




        64.8k887175






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243867%2fhow-to-refer-to-subclasses-in-the-superclass%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Florida Star v. B. J. F.

            Danny Elfman

            Lugert, Oklahoma