How dangerous is setting self.__class__ to something else?

前端 未结 8 697
难免孤独
难免孤独 2020-11-27 18:10

Say I have a class, which has a number of subclasses.

I can instantiate the class. I can then set its __class__ attribute to one of the subclasses. I hav

8条回答
  •  [愿得一人]
    2020-11-27 18:55

    Here's an example of one way you could do the same thing without changing __class__. Quoting @unutbu in the comments to the question:

    Suppose you were modeling cellular automata. Suppose each cell could be in one of say 5 Stages. You could define 5 classes Stage1, Stage2, etc. Suppose each Stage class has multiple methods.

    class Stage1(object):
      …
    
    class Stage2(object):
      …
    
    …
    
    class Cell(object):
      def __init__(self):
        self.current_stage = Stage1()
      def goToStage2(self):
        self.current_stage = Stage2()
      def __getattr__(self, attr):
        return getattr(self.current_stage, attr)
    

    If you allow changing __class__ you could instantly give a cell all the methods of a new stage (same names, but different behavior).

    Same for changing current_stage, but this is a perfectly normal and pythonic thing to do, that won't confuse anyone.

    Plus, it allows you to not change certain special methods you don't want changed, just by overriding them in Cell.

    Plus, it works for data members, class methods, static methods, etc., in ways every intermediate Python programmer already understands.

    If you refuse to change __class__, then you might have to include a stage attribute, and use a lot of if statements, or reassign a lot of attributes pointing to different stage's functions

    Yes, I've used a stage attribute, but that's not a downside—it's the obvious visible way to keep track of what the current stage is, better for debugging and for readability.

    And there's not a single if statement or any attribute reassignment except for the stage attribute.

    And this is just one of multiple different ways of doing this without changing __class__.

提交回复
热议问题