1.1导入模块
使用import语句导入模块
例
import math
导入模块之后,就可以使用该模块下所定义的所有公开的函数、变量和类
>>> math.pow(2, 0.5) # pow是函数
1.4142135623730951
>>> math.pi # pi是变量
3.141592653589793
如果是导入模块下的某几个函数
例:
from math import pow, sin, log
通过import导入模块名,必须通过模块名引用函数名
例:
import math, logging
print math.log(10) # 调用的是math的log函数
logging.log(10, 'something') # 调用的是logging的log函数
通过使用 from import导入可能会引起函数名冲突,则需要别名
例:
from math import log
from logging import log as logger
print log(10)
logger(10, 'import from logging')
1.2动态导入模块
导入模块不存在,python会报importerror错误:
>>> import something
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named something
有时,两个不同的模块提供了相同的功能,如 StringIO和 cStringIO都提供了StringIO这个功能(原因:Python是动态语言,解释执行,因此Python代码运行慢;为了提高python代码的运行速度,可以把某些关键函数用C重写)
StringIO 是纯Python代码编写的,而 cStringIO 部分函数是 C 写的,cStringIO 运行速度更快。
通过typeError错误,动态导入模块:
例:
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
注:try 的作用是捕获错误,并在捕获到指定错误时执行 except 语句。
利用import ... as也可以动态导入不同名称的模块
例:
try:
import json
except ImportError:
import simplejson as json
print json.dumps({'python':2.7})
1.3使用__future__
试用某一新特性,可以通过导入__future__模块的某些功能来实现
例:
#python 2.7 整数除法结果仍是整数
>>> 10 / 3
3
#python3.x 改进了整数的除法运算
>>> 10 / 3
3.3333333333333335
>>> 10
3
在Python 2.7中引入3.x的除法规则,导入__future__的division
>>> from __future__ import division
>>> print 10 / 3
3.3333333333333335
1.4安装第三方模块
python提供的模块管理工具:
esay_insatll
pip(推荐,已内置python2.7.9)
1.5定义类并创建实例
类通过class 关键字定义
例:
class Person(object):
pass
按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的
创建实例使用 类名+(),类似函数调用的形式创建:
xiaoming = Person()
xiaohong = Person()
例:
class Person(object):
pass
xiaoming = Person()
xiaohong = Person()
print xiaoming
print xiaohong
print xiaoming == xiaohong
<__main__.Person object at 0x7fcac56ea450>
<__main__.Person object at 0x7fcac5629ad0>
False
1.6创建实例属性
因为python是动态语言,对每个实例,可以直接给他们属性赋值
例:
xiaoming = Person()
xiaoming.name = 'Xiao Ming'
xiaoming.gender = 'Male'
xiaoming.birth = '1990-1-1'
xiaohong = Person()
xiaohong.name = 'Xiao Hong'
xiaohong.school = 'No. 1 High School'
xiaohong.grade = 2
xiaohong.grade = xiaohong.grade + 1
1.7初始化实例属性
在定义类的时候,可以为该类添加一个特殊的__init__()方法,当创建实例时,__init__()方法被自动调用,就可以为每个实例都统一加上以下属性:
class Person(object):
def __init__(self, name, gender, birth):
self.name = name
self.gender = gender
self.birth = birth
注:__init__() 方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法),后续参数则可以自由指定
xiaoming = Person('Xiao Ming', 'Male', '1991-1-1')
xiaohong = Person('Xiao Hong', 'Female', '1992-2-2')
例:定义Person类的__init__方法,除了接受 name、gender 和 birth 外,还可接受任意关键字参数,并把他们都作为属性赋值给实例。
class Person(object):
def __init__(self,name,gender,birth,**kw):
self.name=name
self.gender=gender
self.birth=birth
for k, v in kw.iteritems():
setattr(self, k, v)
xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
print xiaoming.name
print xiaoming.job
1.8python中访问限制
python中对属性权限的控制是通过变量属性名来实现的,如果一个属性由双下划线开头__,该属性就无法被外部访问。
例:
class Person(object):
def __init__(self, name):
self.name = name
self._title = 'Mr'
self.__job = 'Student'
p = Person('Bob')
print p.name
print p._title
print p.__job
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Person' object has no attribute '__job'
如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"定义的属性在Python的类中被称为特殊属性
以单下划线开头的属性"_xxx"虽然也可以被外部访问,但是,按照习惯,他们不应该被外部访问。
_xxx 可以在子类中使用。__xxx 不可以在子类中使用。
1.9创建类属性
类是模板,而实例则是根据类创建的对象。
实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在class中定义
例:
class Person(object):
address = 'Earth'
def __init__(self, name):
self.name = name
类属性直接绑定在类上的,访问类属性不需要创建实例,可直接访问
print Person.address
所有实例都可以访问到它所属的类的属性
例:
p1 = Person('Bob')
p2 = Person('Alice')
print p1.address
print p2.address
类属性也是可以动态添加和修改的
例:
Person.address = 'China'
print p1.address
# => 'China'
print p2.address
# => 'China'
例:给 Person 类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Person 的实例。
class Person(object):
count = 0
def __init__(self, name):
Person.count = Person.count + 1
self.name = name
p1 = Person('Bob')
print Person.count
p2 = Person('Alice')
print Person.count
p3 = Person('Tim')
print Person.count
>>>1
2
3
注:创建实例必定会调用__init__()方法
2.0类属性和实例属性名冲突怎么办
例:
class Person(object):
address = 'Earth'
def __init__(self, name):
self.name = name
p1 = Person('Bob')
p2 = Person('Alice')
print 'Person.address = ' + Person.address
p1.address = 'China'
print 'p1.address = ' + p1.address
print 'Person.address = ' + Person.address
print 'p2.address = ' + p2.address
结果:
Person.address = Earth
p1.address = China
Person.address = Earth
p2.address = Earth
说明: p1.address = 'China'并没有改变 Person 的 address,而是给 p1这个实例绑定了实例属性address
总结:当实例属性和类属性重名时,实例属性优先级高,将屏蔽掉类属性的访问
在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性。
del p1.address
print p1.address
2.1定义实例方法
实例的私有属性就是以__开头的属性,无法被外部访问,但是从类的内部可以访问。
可以在定义实例的属性,还可以定义实例的方法
实例的方法就是在类中定义的函数,第一个参数永远是self,指向调用该方法的实例本身。
例:
class Person(object):
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
调用实例方法必须在实例上调用:
p1 = Person('Bob')
print p1.get_name()
总结:在实例方法内部,可以访问所有实例属性,如果外部需要访问私有属性,可以通过方法调用获得,这种数据封装的形式除了能保护内部数据一致性外,还可以简化外部调用的难度。
例: Person 类增加一个私有属性 __score,表示分数,再增加一个实例方法 get_grade(),能根据 __score 的值分别返回 A-优秀, B-及格, C-不及格三档。
class Person(object):
def __init__(self, name, score):
self.name=name
self.__score=score
def get_grade(self):
if self.__score >= 80:
return 'A'
if self.__score >= 60:
return 'B'
return 'C'
p1 = Person('Bob', 90)
p2 = Person('Alice', 65)
p3 = Person('Tim', 48)
print p1.get_grade()
print p2.get_grade()
print p3.get_grade()
2.2python中方法也是属性
在class中定义的实例方法其实也是属性,实际上是一个函数对象
例:
class Person(object):
def __init__(self, name, score):
self.name = name
self.score = score
def get_grade(self):
return 'A'
p1 = Person('Bob', 90)
print p1.get_grade
print p1.get_grade()
方法是一个属性,所以可以动态地添加到实例上,通过types.MethodType()把一个函数变成一个方法:
例:
import types
def fn_get_grade(self):
if self.score >= 80:
return 'A'
if self.score >= 60:
return 'B'
return 'C'
class Person(object):
def __init__(self, name, score):
self.name = name
self.score = score
p1 = Person('Bob', 90)
p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
print p1.get_grade()
p2 = Person('Alice', 65)
print p2.get_grade()
给一个实例动态添加方法并不常见,直接在class中定义要更直观
例:
class Person(object):
def __init__(self, name, score):
self.name = name
self.score = score
self.get_grade = lambda: 'A'
p1 = Person('Bob', 90)
print p1.get_grade
print p1.get_grade()
>>>
at 0x7f01d02ab5f0>
A
总结:直接把 lambda 函数赋值给 self.get_grade 和绑定方法有所不同:函数调用不需要传入 self,方法调用需要传入 self
2.3定义类方法
和属性类似,分为实例方法和类方法
在class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。
例:
class Person(object):
count = 0
@classmethod
def how_many(cls):
return cls.count
def __init__(self, name):
self.name = name
Person.count = Person.count + 1
print Person.how_many()
p1 = Person('Bob')
print Person.how_many()
总结:类方法无法获得任何实例变量,只能获得类的引用(因为是在类上调用,而非实例上调用)
译者介绍:家华,从事mysqlDBA的工作,记录自己的一些总结