Както сигурно знаете, в Python писането на тернарен условен преход ternary-if е доста дълъг процес
<cmd A> if <condition> else <cmd B>
докато във всички останали езици обикновено е
<condition> ? <cmd A> : <cmd B>
Това несъмнено е по-грозен и труден за четене начин, но всички са му свикнали – условие, първа команда, втора команда.
Наскоро видях един друг похват използван в два различни плъгина за Django (единият беше south, другият не помня).
<condition> and <cmd A> or <cmd B>
В първите 2 минути като видях този начин на изписване бях доста учуден. Вероятно всеки би бил и вероятно този запис е в пъти по-нечетим от стандартния тернарен-if, но въпреки всичко се доближава повече до обикновения тернарен оператор и сигурно е по-лесен за възприемане от хора с опит в други езици.
Не съм сигурен как точно работи това, но очевидно javascript енджините вече са ненормално бързи, за да е възможно емиулирането на операционна система в браузър. Ако още не вярвате на очите си, най-добре го разгледайте сами – http://bellard.org/jslinux/
Дойде това време от годината, когато човек може да се наслади на изобилие от качествени презентации, благодарение на Google IO. Първото видео, което изгледах беше от Alex Russell, който говори за бъдещия стандарт на Javascript – Harmony. Harmony ще направи опит да очовечи езика, чрез оператори и похвати, които са дефакто-стандарт на повечето функционалните скриптови езици. Все пак не става дума за кардинална промяна, а за “захаросване” на синтаксиса, така че кодът написан за предни версии на езика да си е напълно валиден.
Както и да е, това не е най-интересното от презентацията. Най-интересното от нея е едно изречение, което характеризира перфектно Javascript и очертава основното различие между този език и останалите скриптови езици:
You don’t create classes that are state with behaivour attached,
you create behaivour that holds the state that it needs.
Какво ще направите ако ви трябва динамично създаден модел?
Първосигналното решение е да създадете класа на модела и под него да добавяте полетата. Това е погрешно поради ред причини, но най-основната е, че базовия клас на моделите (models.Model) се създава посредством метаклас (models.base.ModelBase), който е отговорен за магиите под капака и веднъж щом е създаден класа няма как да добавяте нови атрибути и магиите да сработят с тях.
Второсигналното решение е да създадете наследник на метакласа, който да е отговорен за динамичното създаване на желания модел. Това е доста по-елегантно и в стила на Python, а и ще можете да използвате метакласове най-накрая и да се похвалите на приятелите си :D.
class MetaDynamicData(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
newattrs = {'__module__': 'myapp.models'}
# Да речем, че искате да добавите динамично по един атрибут за всеки месец
months = [datetime.datetime(2000, x, 1).strftime('%b').lower() for x in range(1, 13)]
for m in months:
newattrs[m] = models.IntegerField()
return super(MetaDynamicData, cls).__new__(cls, name, (models.Model,), newattrs)
class DynamicData(models.Model):
"""
Dynamic data is cool!
"""
__metaclass__ = MetaDynamicData
Ако не сте чували за метакласове, най-добре си прочетете документацията, за да разберете какво се случва.
Дотук добре, но какво става ако използвате Sphinx, за да си генерирате автоматично документация за кода?!
Рано или късно ще забележите, че документацията за DynamicData липсва. Липсва, защото Python държи описанието на всеки обект (за по-просто docstring) в магическия атрибут __doc__, а класът DynamicData се генерира динамично от метаклас. За това е нужно да създадем docstring-a в __new__ на метакласа.
class MetaDynamicData(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
newattrs = {'__module__': 'myapp.models'}
newattrs['__doc__'] = "Dynamic data is cool!"
# Да речем, че искате да добавите динамично по един атрибут за всеки месец
months = [datetime.datetime(2000, x, 1).strftime('%b').lower() for x in range(1, 13)]
for m in months:
newattrs[m] = models.IntegerField()
return super(MetaDynamicData, cls).__new__(cls, name, (models.Model,), newattrs)
class DynamicData(models.Model):
__metaclass__ = MetaDynamicData
Сега вече всичко ще е наред и ще може да се похвалите на приятелите си, че знаете какво е __doc__, което ви отрежда място в челната петица на най-образованите Python програмисти и завинаги ви прави по-skilled, от който и да е PHP програмист (самият факт, че пишете на Python стига, май).
За съжаление Джанго не е кръстен на този филм, но пък е горе-долу толкова силен…
Ако сте мързелив програмист и не обичате да четете книги или пък харесвате dev конференции и искате да слушате лекции на любимите си гурута, то на драго сърце ще ви препоръчам Ontwik.
Ontwik е сайт, който събира в себе си записи от различни конференции на web тематика и дава възможност на всеки да ги гледа… безплатно. Темите, които следя са предимно Javascript, Ruby, Rails, Python, Django, Git, HTML5, но има още много други. Голямата част от лекциите са наистина качествени и интересни, като има записи на web гурута като David Hansson – създателят на Rails, Tom Werner – един от създателите на Github, Линус Торвалдс, Brendan Eich – създателят на Javascript, и още много други.
Оставям ви с една много готина презентация на David Hansson:
Понякога ми се налага да напиша някое малко парче код html с javascript за прототип или демо. В общия случай това значи, че трябва да създам нов файл, в който да пиша, да отворя редактор, да отворя браузър и милиони натискания на alt+tab в процеса на писане. Въобще досада отвсякъде!
За щастие наскоро попаднах на един много интересен онлайн туул, който предлага цялата тая функционалност наготово. Туулчето се казва jsFiddle и освен, че може да пишете html, css, javascript код директно в браузъра и да виждате резултата своевременно, можете да ползвате и някоя от популярните javascript библиотеки наготово и накрая да споделите готовото парче код в Twitter.