Простое веб приложение на web.py.
Basics of Python and Django. -> Декораторы.
Декораторы
Декораторы - это такая конструкция языка, которая может изменить поведение функции, метода, класса и т.д. не изменяя ее саму.
Это идеальный способ что то изменить в программе без модификации кода изменяемого объекта.
Разберем процесс декорирования функции.
Для начала, рассмотрим некоторые особенности функций.
Присвоение функции переменной.
def greet(name):
return "hello "+name
greet_someone = greet
print greet_someone("John")
# Outputs: hello John
Как видно, функция может быть присвоена переменной как обычное значение и следовательно быть передана как параметр другой функции.
Определение функции внутри другой функции.
def greet(name):
def get_message():
return "Hello %s" % name
result = get_message()+'!'
return result
print greet("John")
# Outputs: Hello John
При определении внутренней функции все переменные, переданные во внешнюю, буду сохранены во внутреннем пространстве (замыкании) внешней функции и доступны из внутренней.
Передача функции как параметра другой функции.
def greet(name):
return "Hello " + name
def call_func(func):
other_name = "John"
return func(other_name)
print call_func(greet)
# Outputs: Hello John
Функция может быть передана параметром и быть вызвана изнутри той функции, в которую была передана.
Функция может возвращать другую функцию.
Иными словами - функция может создавать функцию.
def compose_greet_func():
def get_message():
return "Hello there!"
return get_message
greet = compose_greet_func()
print greet()
# Outputs: Hello there!
Внутрення функция имеет доступ к замыкающему пространству имен внешней.
def compose_greet_func(name):
def get_message():
return "Hello there "+name+"!"
return get_message
greet = compose_greet_func("John")
print greet()
# Outputs: Hello there John!
Обратите внимание на то как мы забираем переменную name из замыкания и возвращаем внутреннюю функцию.
В момент вызова greet = compose_greet_func(“John”) в greet будет находится строка “John”.
Декоратор.
Давайте совместим идеи, изложенные выше и построим декоратор.
Putting the ideas mentioned above together, we can build a decorator. In this example let’s consider a function that wraps the string output of another function by p tags.
В примере предположим, что нам необходимо изменить вывод функции get_text, заключив ее вывод в тэги
.def get_text(name):
return "Hello, {0}".format(name)
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
my_get_text = p_decorate(get_text)
print my_get_text("John")
# <p>Hello, John</p>
Это и был наш первый декоратор.
Т.е. функция-декоратор, принимающаю другую (декорируемую) функцию в качестве аргумента и изменяющая ее поведение.
Поведение изменяется внутри вложенной функции декоратора строкой return “ {0}
Синтаксис декоратора в Python.
Применение декоратора может быть упрощено использованием знака @.
Этот знак - эквивалент процедуры my_get_text = p_decorate(get_text) из примера выше.
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
@p_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
# Outputs <p>lorem ipsum, John dolor sit amet</p>
Now let’s consider we wanted to decorate our get_text function by 3 other functions.
Теперь представим, что нам нужно задекорировать не одной а тремя функциями последовательно, добавив дополнительные теги strong и div.
Определим эти три функции-декоратора.
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def strong_decorate(func):
def func_wrapper(name):
return "<strong>{0}</strong>".format(func(name))
return func_wrapper
def div_decorate(func):
def func_wrapper(name):
return "<div>{0}</div>".format(func(name))
return func_wrapper
With the basic approach, decorating get_text would be along the lines of
При стандартном подходе, чтобы задекорировать всеми тремя нужно выполнить такой код:
get_text = div_decorate(p_decorate(strong_decorate(get_text)))
Однако при использовании синтаксиса декоратора Python это можно написать гораздо проще и понятней.
@div_decorate
@p_decorate
@strong_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
# Outputs <div><p><strong>lorem ipsum, John dolor sit amet</strong></p></div>
Декораторы с аргументом.
Что если нам нужно менять тег, в который мы помещаем вывод декорируемой функции из примеров выше.
Очевидно, для этого тег необходимо передавать в качестве параметра декоратору:
def decorator(opentag,closetag):
def real_decorator(decfunc):
def wrapper(name):
return opentag+' '+ decfunc(name) +' '+closetag
return wrapper
return real_decorator
В таком случае, при декорировании, передаем эти параметры:
@decorator('<h1>','</h1>')
def myf(name):
return name
print myf('Dima')
Basics of Python and Django. -> Рекурсивный коктейль.
Рекурсивный коктейль.
Состоит из 30% воды 20% спирта и 50% рекурсивного коктеля :-).
print("Making recousion coctail!!!")
def make(water,alcohol):
mix = 0
mix = mix + (water*30)
mix = mix + (alcohol*20)
mix = mix + (make(water,alcohol)*50)
return mix
print(make(4,5))
RuntimeError: maximum recursion depth exceeded
Добавим счетчик итерации и ограничим рекурсию.
def make(water,alcohol,cnt):
cnt += 1
mix = 0
mix = mix + (water*30)
mix = mix + (alcohol*20)
if cnt >10:
return mix
mix = mix + (make(water,alcohol,cnt)*50)
return mix
cnt = 0
print(make(4,5,cnt))
Basics of Python and Django. -> Веб-сервер на web.py
WEB.PY
Установка
pip install web.py
Использование.
Простейшее веб приложение сервер.
import web
urls = (
'/', 'hello'
)
app = web.application(urls,globals())#1
class hello:
def GET(self):
return "Hello world!"
if __name__ == "__main__":
app.run()
1 - globals это функция, возвращающая словарь который содержит все переменные, определенные в глобальном прострастве.
Если она вызывается из функции, то возвратит словарь пространства того модуля, где ф-ция была определена а не где ее вызвали.
Запуск на порту 8989.
python server.py 8989
Определение параметра в URL.
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'
if __name__ == "__main__":
app.run()
URL обработака (роутинг)
urls = (
'/', 'index',
/news', 'news',
'/view_news/(\d+)', 'view_news',
)
class index:
...
class news:
...
class view_news:
def GET(self, id):
""" View single news """
post_id = int(id)
Templating
Let’s make a new directory for our templates (we’ll call it templates). Inside, make a new file whose name ends with HTML (we’ll call it index.html). Now, inside, you can just write normal HTML
<em>Hello</em>, world!
Or you can use web.py’s templating language to add code to your HTML:
$def with (name)
$if name:
I just wanted to say <em>hello</em> to $name.
$else:
<em>Hello</em>, world!
Under the first line, add:
import web
render = web.template.render('templates/')
....
def GET(self, name):
return render.index(name)
Databasing
Installing MySQLdb
pip install MySQL-python
First you need to create a database object.
db = web.database(dbn='mysql', user='username', pw='password', db='dbname')
def GET(self, name):
users = db.select('user')
out = 'Hello '
for u in users:
out = out+' '+u.name
return out
Output
Hello dmitry sergey
Insert records
class insert:
def GET(self, name):
n = db.insert('user', name=name)
return 'Ok'
Basics of Python and Django. -> Домашнее задание. Игра Очко.
Домашнее задание.
Написать консольную игру “Очко”.
Правила.
Игроку предлагается выбрать карту (элемент из списка колоды).
Колода имеет вид:
koloda = [2,3,4,5,6,7,8,9,10,11.... и т.д.]
Перед началом игры колода перемешивается.
Игроку последовательно выдается первый элемент карты из списка, при этом элемент удаляется из колоды.
Далее игрок может взять еще карту или прекратить. В случае набора 21 очков либо при прекращении набора вступает в игру компьютер и берет последовательно карты до достижения 18 очков, либо до счета, превышающего счет игрока.
Если компьюьер набирает 18 очков, он прекращает набор и определяется победитель.
Если один из игроков набирает больше 21 он считается проигравшим.
Выигрывает тот у кого больше очков.
Basics of Python and Django. -> Домашнее задание. Импорт компаний.
Импортировать базу компаний.
Сайт flagma.kz
Создать проект Django c такой командой.
from django.core.management.base import BaseCommand, CommandError
from app.models import Person, MainDocuments, Person2Document, Company, City, Person2Company, Import
import re
import psycopg2
import bs4
import requests
import time
def parse_company(c):
try:
city = City.objects.get(name_ru__icontains=c.city_text)
c.city = city
c.save()
except:
print('City not found')
namear = c.faunders_text.split(',')
p = Person()
p.raw_name = namear[0]
p.role = namear[1]
p.source = 'flagma.kz'
p.save()
p.parse()
p2c = Person2Company()
p2c.company = c
p2c.person = p
p2c.save()
print('Saving person %s' % namear[0])
class Command(BaseCommand):
def handle(self, *args, **options):
print('Importing.')
Company.objects.all().delete()
Person.objects.filter(source='flagma.kz').delete()
Person2Company.objects.all().delete()
urls = []
for cnt in range(1,1000):
urls.append('https://flagma.kz/kompanii-k-%s.html' % cnt)
for url in urls:
print("Importing %s" % url)
time.sleep(1)
i = Import()
i.url = url
i.save()
rez = requests.get(url)
soup = bs4.BeautifulSoup(rez.text, 'html.parser')
items = soup.findAll('div',{"class": "page-list-item-info"})
for i in items:
name = i.find('a').text
location = i.find('span',{"itemprop": "location"}).text
boss = i.find('span',{"itemprop": "employee"}).text
arrboss = boss.split(',')
c = Company()
c.name_ru = name
c.name_kz = name
c.faunders_text = boss
c.city_text = location
c.save()
parse_company(c)
print('Saving.....%s' % name)
Создать модель данных для того, чтобы эта команда работала и заполняла таблицу.