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