<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9146193379122430685</id><updated>2011-04-21T23:28:28.358+03:00</updated><category term='linux'/><category term='OOP'/><category term='Python'/><category term='templates'/><category term='sabayon'/><category term='Django'/><title type='text'>FerroHouse</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ferrohouse.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ferrohouse.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ferroman</name><uri>http://www.blogger.com/profile/14060307210289164365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9146193379122430685.post-5014165807053638141</id><published>2008-03-01T22:56:00.005+02:00</published><updated>2008-03-02T17:46:49.897+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OOP'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>ООП как способ сделать мир понятнее. Часть 1.</title><content type='html'>На python.org.ua один из пользователей посетовал на то что не может понять ООП.&lt;br /&gt;Я решил немного помочь ему в этом, а так же всем начинающим питонщикам с той же проблемой.&lt;br /&gt;Надеюсь хоть кому-то пригодится.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Глава 1 или надо же как-то начинать&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Допустим мы хотим написать программу для работы с файлами разных типов. Соответственно в зависимости от типа файла будет добавляться разный функционал, но какой мы пока не знаем.&lt;br /&gt;Что известно точно это те операции что будут производится над файлом в любом случае, в не зависимости от типа. Например такие как "удаление" "копирование" "перенос" а также получение общих атрибутов файла.(размер, имя, тип и т.п)&lt;br /&gt;При написании этой части программы &lt;span style="font-weight:bold;"&gt;без использования ООП&lt;/span&gt; пришлось бы писать просто функцию для каждого действия, просто передавая им путь к файлу. Или использовать библиотечные (входящие в поставку python).&lt;br /&gt;Например так:&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;import os&lt;br /&gt;import shutil&lt;br /&gt;import filecmp&lt;br /&gt;&lt;br /&gt;# path - путь к файлу который мы будем использовать&lt;br /&gt;path = "exemple.txt"&lt;br /&gt;&lt;br /&gt;# операции из стандартних библиотек os и shutil&lt;br /&gt;os.rename(src_path,dst_path)     # переименовать&lt;br /&gt;shutil.copy(src_path,dst_path)   # копировать&lt;br /&gt;shutil.move(src_path,dst_path)   # переместить&lt;br /&gt;os.remove(path)                  # удалить&lt;br /&gt;size = os.path.getsize(path)     # размер файла в байтах&lt;br /&gt;filecmp.cmp(path, path2)         # сравнить файлы&lt;br /&gt;&lt;br /&gt;# теперь немного сложнее&lt;br /&gt;def GetModifyTime(path):&lt;br /&gt;    """ функция полученя времни &lt;br /&gt;    последнего изменения файла """&lt;br /&gt;    from datetime import datetime   # для преобразования даты в приемлемый формат&lt;br /&gt;    return datetime.fromtimestamp(os.path.getmtime(path))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Все вроде бы просто, и вполне понятно и юзабельно. А теперь попробуем сделать практически тоже само но используя ООП-подход.&lt;br /&gt;Для начала создадим некий класс &lt;span style="font-weight:bold;"&gt;FileBase&lt;/span&gt; - этот класс будет представлять наш файл на диске. Что это значит? Это значит что мы привяжем его к некоторому файлу, и все манипуляции будем производить над классом (точнее над одним из его экземпляров).&lt;br /&gt;Про класс следует думать как про нечто, что представляет файл. Как про юриста что представляет человека :) То есть, как про что-то реальное.&lt;br /&gt;&lt;br /&gt;Вот так:&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;import os&lt;br /&gt;import shutil&lt;br /&gt;from datetime import datetime&lt;br /&gt;&lt;br /&gt;# self - это ссылка внутри класса, обозначает&lt;br /&gt;# сам класс. То есть ссылка на самого себя.&lt;br /&gt;class FileBase(object):&lt;br /&gt;    def __init__(self, path):&lt;br /&gt;        """ этот метод (функция класса) вызывается &lt;br /&gt;        при создании копии (экземпляра) класса. &lt;br /&gt;        В нем мы сразу привязываем класс к файлу.&lt;br /&gt;        """&lt;br /&gt;        self.path = path # self.path - это атрибут (параметр) нашего класса в котором записан путь к файлу&lt;br /&gt;&lt;br /&gt;    def __str__(self):&lt;br /&gt;        """Возвращаем путь к файлу &lt;br /&gt;        при вызове экземпляра класса """&lt;br /&gt;        return self.path&lt;br /&gt;&lt;br /&gt;    def rename(self, newname):&lt;br /&gt;        os.rename(self.path, os.path.join(os.path.dirname(self.path), newname))&lt;br /&gt;&lt;br /&gt;    def copy(self, path):&lt;br /&gt;        shutil.copy(self.path,path)&lt;br /&gt;        return FileBase(path) # возвращаем новый объект для файла.&lt;br /&gt;&lt;br /&gt;    def move(self,path):&lt;br /&gt;        shutil.move(self.path, path)&lt;br /&gt;        self.path = path&lt;br /&gt;&lt;br /&gt;    def delete(self):&lt;br /&gt;        """ удаляем файл """&lt;br /&gt;        os.remove(self.path)&lt;br /&gt;        self.path = None&lt;br /&gt;&lt;br /&gt;    def size(self):&lt;br /&gt;        """Возвращаем размер файла"""&lt;br /&gt;        return os.path.getsize(self.path)&lt;br /&gt;&lt;br /&gt;    def __cmp__(self, filobject):&lt;br /&gt;        """сравниваем два файла&lt;br /&gt;        если не равны - возвращаем разницу размеров&lt;br /&gt;        """&lt;br /&gt;        if filecmp.cmp(self.path, filobject):&lt;br /&gt;            return 0&lt;br /&gt;        else:&lt;br /&gt;            return self.size - filobject.size&lt;br /&gt;&lt;br /&gt;    def getModifyTime(self):&lt;br /&gt;        """возвращаем время последней модификации файла"""&lt;br /&gt;        return datetime.fromtimestamp(os.path.getmtime(self.path))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Сложнее немного не так ли? Но на самом деле это кажущаяся сложность, и почему мы увидим дальше.&lt;br /&gt;Хочу обратить внимание, что &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;rename&lt;/span&gt;&lt;/span&gt; в классе несколько не тот что в стандартной функции.&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;os.rename(src_path,dst_path) &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;При вызове этой функции переименованный файл будет перемещён в папку &lt;span style="font-weight:bold;"&gt;dst_path&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt; под новым именем. В случае же с классом то вызов метода &lt;span style="font-weight:bold;"&gt;rename&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt; не переместит файл, а просто переименует его в той папке где он находится.&lt;br /&gt;С функцией сравнения тоже есть отличия, я расскажу о них дальше.&lt;br /&gt;&lt;br /&gt;Вот теперь давайте посмотрим как произвести одни и те же операции используя наш класс и без него:&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;print "без использования ООП"&lt;br /&gt;# для начала возьмем файл&lt;br /&gt;path = "c:\\test\\test2\\example.txt"&lt;br /&gt;print os.path.getsize(path) # выводим размер файла&lt;br /&gt;print GetModifyTime(path) # выводим дату создания&lt;br /&gt;# где сейчас файл?&lt;br /&gt;print path&lt;br /&gt;# перемещаем файл в другую папку:&lt;br /&gt;dst = "c:\\test\\"+os.path.basename(path) # путь к новому файлу&lt;br /&gt;shutil.move(path,dst)&lt;br /&gt;# где теперь?&lt;br /&gt;print dst&lt;br /&gt;# копируем обратно&lt;br /&gt;shutil.copy(dst,path)   # копировать&lt;br /&gt;# где теперь файлы?&lt;br /&gt;print "Файл - " + fileobj.path&lt;br /&gt;print "Копия файла" + copy_fileobj.path&lt;br /&gt;print GetModifyTime(path) # выводим дату последней модификации копии&lt;br /&gt;# сравниваем файлы:&lt;br /&gt;if filecmp.cmp(path, dst):&lt;br /&gt;    print "одинаковые"&lt;br /&gt;else:&lt;br /&gt;    print "разные"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;отлично. Теперь то же но с использованием нашего класса:&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;fileobj = FileBase("c:\\test\\test2\\example.txt") # теперь fileobj - наш файл&lt;br /&gt;print fileobj.size() # выводим размер файла&lt;br /&gt;print fileobj.getModifyTime() # выводим дату последней модификации&lt;br /&gt;# где сейчас файл?&lt;br /&gt;print fileobj&lt;br /&gt;# перемещаем в другую папку&lt;br /&gt;fileobj.move("c:\\test\\"+os.path.basename(fileobj))&lt;br /&gt;# где теперь?&lt;br /&gt;print fileobj&lt;br /&gt;# ок, копируем обратно одновременно получая объект копии файла&lt;br /&gt;copy_fileobj = fileobj.copy("c:\\test\\test2\\example.txt")&lt;br /&gt;# гд теперь файлы?&lt;br /&gt;print "Файл - " + fileobj&lt;br /&gt;print "Копия файла" + copy_fileobj&lt;br /&gt;# можно посмотреть дату последней подификации копии&lt;br /&gt;print copy_fileobj.getModifyTime()&lt;br /&gt;# сравним файл с копией&lt;br /&gt;if fileobj == copy_fileobj:&lt;br /&gt;    print "одинаковые"&lt;br /&gt;else:&lt;br /&gt;    print "разные"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Обратите внимание что оба файла &lt;span style="font-weight:bold;"&gt;сравниваются как обычные переменные&lt;/span&gt;. Можно также узнать какой из них больше, а какой меньше, наитивно, как у переменных. В не-ООП стиле пришлось бы писать и явно вызывать спец. функцию.&lt;br /&gt;&lt;br /&gt;Я думаю разница уже заметна. Мы делали одни и те же вещи, но в случае с ООП мы оперируем некоторым &lt;span style="font-weight:bold;"&gt;объектом&lt;/span&gt; который &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;представляет&lt;/span&gt; файл&lt;/span&gt;. Он его представляет и манипулирует им, порождая новые объекты-представители при копировании, изменяя собственные свойства при переносе и т.д. Так если бы мы делали это в файловом менеджере, например.&lt;br /&gt;Без ооп - мы манипулируем файлами, относясь к нему непосредственно через пути, что несколько запутывает саму программу. &lt;span style="font-style:italic;"&gt;Разница пока невелика, но стало немного проще.&lt;/span&gt;&lt;br /&gt;Самое интересное что улучшение понятности программы при правильном использовании - не самое главное преимущество ООП. В следующем посте я расскажу про преимущество несколько более важное.&lt;br /&gt;Я расскажу про наследование.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9146193379122430685-5014165807053638141?l=ferrohouse.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ferrohouse.blogspot.com/feeds/5014165807053638141/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9146193379122430685&amp;postID=5014165807053638141' title='Комментарии: 6'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/5014165807053638141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/5014165807053638141'/><link rel='alternate' type='text/html' href='http://ferrohouse.blogspot.com/2008/03/1.html' title='ООП как способ сделать мир понятнее. Часть 1.'/><author><name>Ferroman</name><uri>http://www.blogger.com/profile/14060307210289164365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9146193379122430685.post-1954896514605919648</id><published>2008-02-11T14:18:00.000+02:00</published><updated>2008-02-11T14:31:38.186+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sabayon'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Поставил Sabayon Linux</title><content type='html'>После долгих спотыканий и попыток поставить &lt;a href="http://www.gentoo.org"&gt;Gentoo&lt;/a&gt;, в результате поставил себе &lt;a href="http://sabayonlinux.org"&gt;Sabayon Linux&lt;/a&gt; - это дистрибутив на базе того же Gentoo со всеми вытекающими последствиями. Что понравилось    - работа из коробки + хороший инсталятор +отличная поддержка граф. плат. Никаких танцев с бубном, все запустилось и сразу заработало со всеми эффектами и ускорением. Не понравилось (точнее просто немного расстроило) - слишком много всего ставится сразу. Я бы все-таки хотел ставить не все, а только то что хочу. Учитывая практическое отсутствие интеренета дома, это не большая проблема, - дойдут руки, удалю лишнее. Ну и хотелось бы xfce вместо кде/гнома, но это я придираюсь :)&lt;br /&gt;Попробуйте, для старта в gentoo - самое то.&lt;br /&gt;Единственное что меня реально смущает в линуксе - отсутсвие нормального файлового менеджера. Ну не привык я мышкой тыкать, мне бы что-то типа TotalCommander, или Far'а. mc - не то.&lt;br /&gt;Кто чем пользуется?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9146193379122430685-1954896514605919648?l=ferrohouse.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ferrohouse.blogspot.com/feeds/1954896514605919648/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9146193379122430685&amp;postID=1954896514605919648' title='Комментарии: 6'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/1954896514605919648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/1954896514605919648'/><link rel='alternate' type='text/html' href='http://ferrohouse.blogspot.com/2008/02/sabayon-linux.html' title='Поставил Sabayon Linux'/><author><name>Ferroman</name><uri>http://www.blogger.com/profile/14060307210289164365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9146193379122430685.post-8516950986935968590</id><published>2007-12-09T20:31:00.000+02:00</published><updated>2007-12-09T20:38:53.029+02:00</updated><title type='text'>Syntax Highlighter в Blogger'е</title><content type='html'>При написании предыдущего поста первая проблема которая у меня возникла  - это подсветка кода.&lt;br /&gt;После довольно долгих поисков было найдено отличное решение - &lt;a href="http://fazibear.blogspot.com/2007/09/blogger-syntax-higlighter.html"&gt;Syntax Highligter Widget&lt;/a&gt; на базе &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt; 1.5.1 , за что огоромное спасибо Carl Mason'у aka FaziBear.&lt;br /&gt;Просто нажмите &lt;a href="http://fazibear.googlepages.com/blogger.html"&gt;Add to Blogger&lt;/a&gt;.&lt;br /&gt;Как пользоваться написано &lt;a href="http://code.google.com/p/syntaxhighlighter/wiki/Usage"&gt;здесь&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9146193379122430685-8516950986935968590?l=ferrohouse.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ferrohouse.blogspot.com/feeds/8516950986935968590/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9146193379122430685&amp;postID=8516950986935968590' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/8516950986935968590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/8516950986935968590'/><link rel='alternate' type='text/html' href='http://ferrohouse.blogspot.com/2007/12/syntax-highlighter-blogger.html' title='Syntax Highlighter в Blogger&apos;е'/><author><name>Ferroman</name><uri>http://www.blogger.com/profile/14060307210289164365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9146193379122430685.post-3608985904333065831</id><published>2007-12-08T23:08:00.001+02:00</published><updated>2008-03-02T17:48:03.196+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Django'/><category scheme='http://www.blogger.com/atom/ns#' term='templates'/><title type='text'>Интересный tip пр работе с словарями в темплейтах Dajngo</title><content type='html'>Есть маленький "tip" при работе с словарями в темплейтах Джанги - если вы используете словарь списков. Например вот так запишем праздничные дни в месяце.&lt;br /&gt;&lt;textarea name="code" class="python" /&gt;&lt;br /&gt;monthlist = {'April':(1,2,3), 'May':(5,6,8)}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;Теперь нам нужно добраться до каждой записи словаря в темплейте.&lt;br /&gt;&lt;textarea name="code" class="html" /&gt;&lt;br /&gt;{% for monthname in monthlist.items %}&lt;br /&gt;  {{monthname.0}} // названия месяца&lt;br /&gt;  {% for holiday in monthname.1 %} // получаем все записи из списка&lt;br /&gt;     {{ holiday}}&lt;br /&gt;  {% endfor %}&lt;br /&gt;{% endfor %}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;Для меня было не очевидно.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9146193379122430685-3608985904333065831?l=ferrohouse.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ferrohouse.blogspot.com/feeds/3608985904333065831/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9146193379122430685&amp;postID=3608985904333065831' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/3608985904333065831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9146193379122430685/posts/default/3608985904333065831'/><link rel='alternate' type='text/html' href='http://ferrohouse.blogspot.com/2007/12/tip-dajngo.html' title='Интересный tip пр работе с словарями в темплейтах Dajngo'/><author><name>Ferroman</name><uri>http://www.blogger.com/profile/14060307210289164365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
