python - Create current class default instance in its base class -
preamble: have objects, of them created default constructor , left without modifications, such objects considered "empty". need verify whether object "empty" or not. done in following way (majik methods implemented in base class animal):
>>> = bird() >>> b = bird() >>> == b true >>> == bird() true so the question: possible (and if yes how) achieve such syntax:
>>> == bird.default true at least 1 (but previous sweeter):
>>> == a.default true but: implementation of default in base class animal (to not repeat in derived classes):
class animal(object):    ... tech stuff ...         - obj comparison         - obj representation         - etc  class bird(animal):    ... birds ...  class fish(animal):    ... fishes ... of course don't need solutions have bird() calling in animal class :)  
i'd have kind of templating implemented in base class stamp out derived class default instance , store unique copy in derived class or instance property. think achieved playing metaclasses or so, don't know how.
class default instance considered object instantiated __init__() of class (without further object modification of course).
update
the system flooded objects , want have possibility separate circulating of freshly (by default) created objects (which useless display example) somehow modified one. by:
if == bird():     . . . i don't want creation of new object comparison, intuitevly, i'd have 1 instance copy etalon instances of class compare with. objects json-like , contain properties (besides implicit __str__, __call__, __eq__ methods), i'd keep such style of using built-in python features , avoid using explicitly defined methods is_empty() example. it's entering object in interactive shell , prints out calling __str__, implicit, fun.
to achieve first solution should use metaclass.
for example:
def add_default_meta(name, bases, attrs):     cls = type(name, bases, attrs)     cls.default = cls()     return cls and use as(assuming python3. in python2 set __metaclass__ attribute in class body):
class animal(object, metaclass=add_default_meta):     # stuff  class nameclass(animal, metaclass=add_default_meta):     # stuff note have repeat metaclass=... every subclass of animal.
if instead of function use class , __new__ method implement metaclass, can inherited, i.e:
class adddefaultmeta(type):     def __new__(cls, name, bases, attrs):         cls = super(adddefaultmeta, cls).__new__(cls, name, bases, attrs)         cls.default = cls()         return cls a different way achieve same effect use class decorator:
def add_default(cls):     cls.default = cls()     return cls   @add_default class bird(animal):    # stuff again, must use decorator every subclass.
if want achieve second solution, i.e. check a == a.default, can reimplement animal.__new__:
class animal(object):     def __new__(cls, *args, **kwargs):         if not (args or kwargs) , not hasattr(cls, 'default'):             cls.default = object.__new__(cls)             return cls.default         else:             return object.__new__(cls) this create empty instance whenever first instance of class created , stored in default attribute.
this means can both:
a == a.default and
a == bird.default but accessing bird.default gives attributeerror if didn't create bird instance.
style note: bird.default looks bad me. default instance of bird not type, hence should use lowercase_with_underscore according pep 8.
in fact whole thing looks fishy me. have is_empty() method. it's pretty easy implement:
class animal(object):     def __init__(self, *args, **kwargs):         # might require more complex condition         self._is_empty = not (bool(args) or bool(kwargs))     def is_empty(self):         return self._is_empty then when subclasses create empty instance doesn't pass arguments base class _is_empty attribute true , hence inherited method return true accordingly, while in other cases argument passed base class set _is_empty false.
you can play around in order obtain more robust condition works better subclasses.
Comments
Post a Comment