Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
>>> class A(object): pass
>>> class B(object): pass
>>> a=A()
>>> a.__class__
<class '__main__.A'>
>>> a.__class__=B
>>> a.__class__
<class '__main__.B'>
>>> a.__class__={}.__class__
TypeError Traceback (most recent call last)
/home/seriy/<ipython console> in <module>()
TypeError: __class__ assignment: only for heap types
>>> a.__class__=dict
TypeError Traceback (most recent call last)
/home/seriy/<ipython console> in <module>()
TypeError: __class__ assignment: only for heap types
static int
object_set_class(PyObject *self, PyObject *value, void *closure)
{
PyTypeObject *oldto = Py_TYPE(self);
PyTypeObject *newto;
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
"can't delete __class__ attribute");
return -1;
}
if (!PyType_Check(value)) {
PyErr_Format(PyExc_TypeError,
"__class__ must be set to new-style class, not '%s' object",
Py_TYPE(value)->tp_name);
return -1;
}
newto = (PyTypeObject *)value;
if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
!(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))
{
PyErr_Format(PyExc_TypeError,
"__class__ assignment: only for heap types");
return -1;
}
if (compatible_for_assignment(newto, oldto, "__class__")) {
Py_INCREF(newto);
Py_TYPE(self) = newto;
Py_DECREF(oldto);
return 0;
}
else {
return -1;
}
}
http://example.com/user_%{user_id}d.jsonвозвращает либо JSON список либо JSON объект для юзера user_id. Нам нужно вернуть клиенту список загруженных профилей, но из них будет использоваться только один-два, неизвестно какие.
def get_profiles(user_ids):
profiles=[]
for id in user_ids:
profile=json.decode(urllib.open("http://example.com/user_%d.json"%id).read())
profukes.append(profile)
return profiles
def get_profiles_lazy(user_ids):
profiles=[]
for id in user_ids:
profile=lazy_loader(id)
profukes.append(profile)
return profiles
res1=get_profiles_lazy(user_ids)
res2=get_profiles(user_ids)
assert type(res1[1]) == type(res2[1])
assert res1[1].field == res2[1].field
class lazy_loader(object):
def _res(self):
if not self._result:
self._result=json.decode(urllib.open("http://example.com/user_%d.json"%self.id).read())
return self._result
def __getattribute__(self, name):
if name in ['_result', '_res', 'master', 'id']:#don't proxy requests for own properties
return super(lazy_mask, self).__getattribute__(name)
else:#but proxy requests for masked object
return self._res().__getattribute__(name)
>>> import urllib2
>>> uri = 'http://habrahabr.ru/blogs/t/{0}'
>>> def lazy(article_id):
... yield urllib2.urlopen(uri.format(article_id))
...
>>> b = lazy(114590)
>>> b
<generator object lazy at 0x10256f780> # URI еще не открывалось
>>> next(b) # Открываем
<addinfourl at 4334244568 whose fp = <socket._fileobject object at 0x10256b750>>
>>> Dict = {}.__class__
>>> class Foo(Dict):
... pass
...
>>> f = Foo()
>>> f['herp']='derp'
>>> f
{'herp': 'derp'}
>>>
Более того object, и type — это объекты типа (классы), и у них тоже есть специальные атрибуты __name__, __bases___
Заметки об объектной системе языка Python ч.2