由于本次学习笔记中有很多内容是从网上查找资料学习后,自行整理的产物,故文章分类标为转载。
Python学习笔记
输入输出
利用print语句输出,eg. print ‘100 + 200 = ’ , 100 + 200
利用raw_input进行输入,eg. name = raw_input()
格式化输出:格式化方法与C语言一样。eg. ‘Hi, %s, you have $%d.’ %(‘Michael’, 1000)一些数据类型
python的基础数据类型与其他编程语言的数据类型相似,只是一些细节上有点不同:
字符串内部的’和”用转义字符\表示。python允许’’’…’’’的格式表示多行内容。Bool值的运算使用的是and,or和not。空值用None表示。python是动态语言,变量可以不用提前声明直接用。
python中的字符串:Python提供了ord()和chr()函数,可以把字母和对应的数字相互转换。还可以利用encode函数进行编码的转换。
python中的list用起来有点像C++中STL里定义的Array,它有一些比较方便的函数,如,append,insert,pop等。数组越界会报一个IndexError的错误。支持负的数组下标,意思为倒数第n个下标。
tuple类似于Haskell中的元组,这个大家都了解,不再赘述。需要注意的是:空的tuple定义为(),而只含有一个元素的tuple需要定义为(x, )的形式,即必须要加’,’来消除歧义。
dict使用键-值存储,查找起来灰常方便。定义的格式就像d = {'Michael': 95, 'Bob': 75, 'Tracy': 85},使用的时候d['Michael']就会返回95。或者调用类似于d.get('Thomas')的方法来得到想要的值。
set类似于数学当中集合的概念,重复的元素会被去掉。通过add(key)可以添加元素到set中,通过remove(key)可以删除元素。也可以做交集并集的操作eg.>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
set([2, 3])
>>> s1 | s2
set([1, 2, 3, 4])
条件判断和循环
条件判断:if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
循环:(通过一些示例代码来展示)
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print name
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print sum
关于函数
函数的定义格式通过一个示例代码来看:
def my_abs(x):
if x >= 0:
return x
else:
return –x
定义空函数:
def nop():
pass
空语句都能用pass
python允许函数返回“多个值”,(其实是返回了一个tuple)
Python允许函数有默认值,其方式类似于C++中的默认值参数的形式,这里不赘述。唯一需要注意的是python中的默认参数是指向了一个不变的对象。即:
def add_end(L=[]):
L.append('END')
return L
若是这个函数调用时就会出现一个奇怪的现象:
>>> add_end()
['END‘]
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
即每次调用的时候改的都是同一个对象。
一些看起来比较高大上的特性
切片:(list和tuple都可以用切片)
L = range(100)
L[x : y]表示从第x个取到第y个
L[0 : 10 : 2]表示前十个数,每两个取一个
L[: : 5]表示所有数,每5个取一个。
列表生成式:
range(1, 11)<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">表示[1, 2, 3, 4, 5, 6,7, 8, 9, 10]</span>
[m + n for m in 'ABC' for n in 'XYZ']<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">表示['AX','AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']</span>
生成器:
Python中有一种一边循环一边计算的机制,叫做生成器(Generator)。有两种构成生成器的方法。第一种是将上面列表生成式中的方括号改为小括号即可。第二种是利用函数改造。
python支持函数式编程的特性
面向对象编程
类的定义:(通过代码实例来看)
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
上面的__init__方法相当于构造函数,常常用于给类绑定成员变量。__init__的第一个参数永远是self,表示创建的实例本身。其他成员函数可以自由定义。
访问限制:
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线。实例的变量名如果以两个下划线开头就变成了一个私有变量。
在python中,变量名类似__xxx__的,也就是以双下划线开头和结尾的变量名,是特殊变量,特殊变量是可以从外部直接访问的。
但是需要注意的一点是:上述所谓私有变量其实仍然可以在外部访问到。这是因为Python解释器对外把__name变量改成了_Student__name(假设该类的名字叫做Student)
类的继承和多态:(仍旧以代码实例来看)
class Animal(object):
def run(self):
<span style="white-space:pre"> </span>print 'Animal is running...'
class Dog(Animal):
def run(self):
<span style="white-space:pre"> </span>print 'Dog is running...'
def eat(self):
<span style="white-space:pre"> </span>print 'Eating meat...'
继承的方法从上面已经可以比较容易的看出来了,若是多重继承,就在类的名字后面的那个括号中写出要继承的所有类的名字,且用逗号隔开;至于多态的用法,与C++中的类似
type()函数可以判断对象类型;isinstance()函数可以判断类的继承关系;dir()函数可以获得一个对象的所有属性和方法。还有与其他语言类似的一些关于类的属性的函数,如:getattr(),setattr(),hasattr()等
创建了一个类的实例之后,动态绑定成员变量的方法和javascript是一样的,即用的时候直接现用现绑定即可。而动态绑定成员函数的方法如下:
>>> def set_age(self, age): # 定义一个函数作为实例方法
... self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法
>>> s.set_age(25) # 调用实例方法
>>> s.age # 测试结果
25
但上述方法只是给一个已经创建好的实例绑定方法。要给一个class绑定方法,只需要改变上面的一句话:
s.set_age = MethodType(set_age, None, Student)
但是动态绑定成员就会带来一个问题,就是比较乱,因为到处都有可能添加成员。这时,也许可以用__slot__用来限制class的属性。比如只允许对Student实例添加name和age属性可以这样:
>>> class Student(object):
... __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
...
Python内置的装饰器@property装饰器可以把一个方法变成一个属性调用:
class Student(object):
@property
def birth(self):
<span style="white-space:pre"> </span>return self._birth
@birth.setter
def birth(self, value):
<span style="white-space:pre"> </span>self._birth = value
@property
def age(self):
<span style="white-space:pre"> </span>return 2014 - self._birth
上面的birth就是可读可写的属性,而age就是一个只读的属性。
前面提到的以双下划线开头和结尾的特殊变量是由特殊作用的,可以用来定制类。比如要使一个类的实例能按自己想要的格式print出来,就需要实现一个__str__(self)函数;要想让自己的类可以迭代,就像list那样,就需要实现一个__iter__(self)函数;要想像list那样通过下标找到元素,需要实现__getitem__(self)函数;要想让类能动态返回一个属性,则需要实现一个__getattr__(self, attr)函数等等。
错误处理
和其他很多编程语言一样,Python中也有try…except…finally…语句,下面以一个实例来看:
try:
print 'try...'
r = 10 / int('a')
print 'result:', r
except ValueError, e:
print 'ValueError:', e
except ZeroDivisionError, e:
print 'ZeroDivisionError:', e
finally:
print 'finally...'
print 'END'
文件读写
读文件:f = open(‘/Users/Michael/test.txt’, ‘r’) //打开文件
f.read() //调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示。
f.close() //关闭文件
还有一个更加简洁安全的方法是:
with open('/path/to/file', 'r') as f:
print f.read()
写文件:
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
Python与MySQL
由于MySQL服务器以独立的进程运行,并通过网络对外服务,所以,需要支持Python的MySQL驱动来连接到MySQL服务器。目前有两个MySQL驱动:
mysql-connector-python:是MySQL官方的纯Python驱动;
MySQL-python:是封装了MySQL C驱动的Python驱动。
我们以mysql-connector-python为例,演示如何连接到MySQL服务器的test数据库:
# 导入MySQL驱动:
>>> import mysql.connector
# 注意把password设为你的root口令:
>>> conn = mysql.connector.connect(user='root', password='password', database='test', use_unicode=True)
>>> cursor = conn.cursor()
# 创建user表:
>>> cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
# 插入一行记录,注意MySQL的占位符是%s:
>>> cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'Michael'])
>>> cursor.rowcount
1
# 提交事务:
>>> conn.commit()
>>> cursor.close()
# 运行查询:
>>> cursor = conn.cursor()
>>> cursor.execute('select * from user where id = %s', '1')
>>> values = cursor.fetchall()
>>> values
[(u'1', u'Michael')]
# 关闭Cursor和Connection:
>>> cursor.close()
True
>>> conn.close()
其他
Python的内容还是很丰富的,比如还可以用它操作文件和目录,进程编程等,还有调试和单元测试的方法,许多许多非常有用的第三方模块等等。这里暂时就不多做介绍了。
Django学习笔记
Django中文文档的官方网站的文档比较详尽。这里先附上网址:http://django-chinese-docs.readthedocs.org/en/latest/。(不过貌似被墙了。。)
由于此次时间较紧,未能仔细详尽的看这些文档。因此,对于Django的介绍可能暂时会比较肤浅,简单。
设计模型
让我们先通过一个简单的例子来看:class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __unicode__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
return self.headline
manage.py syncdb
syncdb命令会查找你所有可用的模型,然后在你的数据库中创建还不存在的数据库表。
利用提供的各种方便的API
通过Python提供的各种方便的API,我们可以方便的访问我们的数据:http://django-chinese-docs.readthedocs.org/en/latest/topics/db/queries.html。由于时间原因,对于很多API还没有好好研究,这可以之后再详细看看。
管理接口
一旦我们定义好了models,Django可以创建一个管理界面(可让授权用户添加、修改和删除对象)。要用这个只需在admin site中注册我们模型即可:
# In models.py...
from django.db import models
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
# In admin.py in the same directory...
import models
from django.contrib import admin
admin.site.register(models.Article)
设计URLs
官方的文档给了一些说明,个人感觉说的不是很明白,但是给的代码还是比较一目了然的,所以我们还是看代码吧:
from django.conf.urls import patterns
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
上面的代码映射了 URLs ,从一个简单的正则表达式,到 Python 回调函数(“views”)所在的位置。正则表达式通过圆括号来“捕获” URLs 中的值。当一个用户请求一个页面时, Django 将按照顺序去匹配每一个模式,并停在第一个匹配请求的 URL 上。(如果没有匹配到, Django 将会展示一个404的错误页面。)
例如:如果一个用户请求了个 URL “/articles/2005/05/39323/”, Django 将会这样调用函数news.views.article_detail(request, '2005', '05', '39323').编写视图
一个视图会根据参数检索数据,加载一个模板并根据这个模板呈现检索出来的数据:def year_archive(request, year):
a_list = Article.objects.filter(pub_date__year=year)
return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})
设计模板
{% extends "base.html" %}
{% block title %}Articles for {{ year }}{% endblock %}
{% block content %}
<h1>Articles for {{ year }}</h1>
{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}
变量用双花括号包围。Django有“模板继承”的概念。即上面代码中的{% extends "base.html" %}。每一个模板只需定义它独特的部分即可。
其他
上面仅仅是一个比较简单的介绍,具体的技术细节我们还需要在之后的过程中继续学习。
最后预祝我们的微信开发项目能进展顺利~加油~