Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
class AttributeInitType(object):
def __call__(self, *args, **kwargs):
""" Вызов класса создает новый объект. """
# Перво-наперво создадим сам объект...
obj = type.__call__(self, *args)
# ...и добавим ему переданные в вызове аргументы в качестве атрибутов.
for name in kwargs:
setattr(obj, name, kwargs[name])
# вернем готовый объект
return obj
class Man(object):
__metaclass__ = AttributeInitType
me = Man(height = 180, weigth = 80)
print me.height
>>> Traceback (most recent call last):
File "/tmp/py7637jbF", line 13, in <module>
class Man(object):
TypeError: Error when calling the metaclass bases
object.__new__() takes no parameters
class Apple(Model):
pass
Apple.objects.all()
def get_query_set(self):
"""Returns a new QuerySet object. Subclasses can override this method
to easily customize the behavior of the Manager.
"""
return QuerySet(self.model)
def all(self):
return self.get_query_set()
def all(self):
"""
Returns a new QuerySet that is a copy of the current one. This allows a
QuerySet to proxy for a model manager in some cases.
"""
return self._clone()
def filter(self, *args, **kwargs):
"""
Returns a new QuerySet instance with the args ANDed to the existing
set.
"""
return self._filter_or_exclude(False, *args, **kwargs)
def _filter_or_exclude(self, negate, *args, **kwargs):
if args or kwargs:
assert self.query.can_filter(), \
"Cannot filter a query once a slice has been taken."
clone = self._clone()
if negate:
clone.query.add_q(~Q(*args, **kwargs))
else:
clone.query.add_q(Q(*args, **kwargs))
return clone
>>>type(type) <type 'type'>
>>> isinstance(object, type) True >>> isinstance(type, object) True >>>
Итак, классический ООП подразумевает наличие только классов и объектов.
>>> ClassOfPythons = type('ThePython', (object,), {'voice': 'sh-sh-sshhhhhh....'})
>>> squasher = ClassOfPythons()
>>> squasher.voice
sh-sh-sshhhhhh....
ClassOfPythons = object.__class__('ThePython', (object,), {'voice': 'sh-sh-sshhhhhh....'})
from types import *
def delete(mylist, item):
if type(item) is IntType:
del mylist[item]
else:
mylist.remove(item)
Приятно, конечно, что прототипы позволяют избавиться от лишнего слоя абстракций в виде классов и, тем более, метаклассов. Более того, эти сущности при желании можно моделировать средствами JS.
Использование метаклассов в Python