Python进阶(三)
来源:互联网 发布:windows图形编程pdf 编辑:程序博客网 时间:2024/05/17 03:18
一.Python模块
导入模块:
>>> import math>>> math.pow(2,2)4.0>>>
导入指定函数:
>>> from math import pow,sin,log>>> pow(2,10)1024.0>>> sin(90)0.8939966636005579>>>
使用from example import function时出现的名字冲突问题:
>>> from math import log>>> from logging import log as logger>>> print log(10)2.30258509299>>> logger(10,'importt from logging')>>>
动态导入模块:try:except ImportError:
>>> try:from cStringIO import StringIOexcept ImportError:from StringIO import StringIO
使用__future__:
当新版本的一个特性与旧版本不兼容时,该特性将会在旧版本中添加到__future__中,以便旧的代码能在旧版本中测试新特性。
要试用某一新的特新,就可以导入__future__模块的功能来实现
在Python 2.7中:
>>> 10 / 33在Python 3.x中:
>>> 10 / 33.3333333333333335>>> 10 // 33在2.7中试用3.x的功能:
>>> from __future__ import division>>> print 10 / 33.3333333333333335
Python管理第三方模块的方式:
1.easy_install
2.pip(推荐,内置在2.7.9中)
确保安装了pip的情况下在命令提示符输入:pip install web.py(//第三方模块)等待下载就可以了
二.Python面向对象特征:
创建一个类,初始化两个该类的示例,进行打印和对比操作:
class Person(object): passxiaoming=Person()xiaohong=Person()print xiaomingprint xiaohongprint xiaoming==xiaohong>>><__main__.Person object at 0x02840970><__main__.Person object at 0x0295C650>False创建一个类,初始化三个类的实例,给增加属性(python是动态语言,对于每个属性都直接可以给他们赋值):
class Person(object): passp1 = Person()p1.name = 'Bart'p2 = Person()p2.name = 'Adam'p3 = Person()p3.name = 'Lisa'L1 = [p1, p2, p3]L2 = sorted(L1,lambda p1,p2:cmp(p1.name,p2.name))print L2[0].nameprint L2[1].nameprint L2[2].name>>>AdamBartLisa
尽管python可以给示例随便增加属性,但是,现实世界中同一个类应该拥有相同的属性,此时我们使用__init__() 方法来同意定义属性,类似java中的构造方法,第一个参数必须是self,如下:
class Person(object): def __init__(self, name, gender, birth): self.name = name self.gender = gender self.birth = birth创建实例的时候我们就可以这样了:
xiaoming = Person('Xiao Ming', 'Male', '1991-1-1')xiaohong = Person('Xiao Hong', 'Female', '1992-2-2')试编写除了接受固定参数之外还可以接受不确定的参数:**kw
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.nameprint xiaoming.job
访问限制:
属性前面加 '__' (双下划线) 就无法被外部访问。
xiaoming.__name='Xiao Ming'前后都加 '__' 的为特殊属性,python中有很多预定义的特殊属性可以用,通常我们不需要把普通属性用 __xxx__ 定义。以单下划线开头的属性"_xxx"虽然也可以被外部访问,但是,按照习惯,他们不应该被外部访问。
class Person(object): def __init__(self,name,score): self.name=name self.__score=scorep=Person('Bob',69)print p.nameprint p.__score>>>Traceback (most recent call last): File "C:/Users/Administrator.2013-20140717HS/Desktop/aaa", line 7, in <module> print p.__scoreAttributeError: 'Person' object has no attribute '__score'
创建类属性:
class Person(object): sex='M' def __init__(self,name,score): self.name=name self.score=scorep1=Person('Bob',69)p2=Person('Jim',89)print p1.sexprint p1.sex>>> MM>>>类属性也可以动态创建:
class Person(object): sex='M' def __init__(self,name,score): self.name=name self.score=scorePerson.countrycode='CN'p1=Person('Bob',69)p2=Person('Jim',89)print p1.sexprint p1.sexprint p1.countrycodeprint p1.countrycode>>> MMCNCN>>>
类属性和示例属性冲突时:
class Person(object): address = 'Earth' def __init__(self, name): self.name = namep1 = Person('Bob')p2 = Person('Alice')print 'Person.address = ' + Person.addressp1.address = 'China'print 'p1.address = ' + p1.addressprint 'Person.address = ' + Person.addressprint 'p2.address = ' + p2.address>>>Person.address = Earthp1.address = ChinaPerson.address = Earthp2.address = Earth可见,可见,当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。
原因是 p1.address = 'China'并没有改变 Person 的 address,而是给 p1这个实例绑定了实例属性address ,对p1来说,它有一个实例属性address(值是'China'),而它所属的类Person也有一个类属性address,所以:
访问 p1.address 时,优先查找实例属性,返回'China'。
访问 p2.address 时,p2没有实例属性address,但是有类属性address,因此返回'Earth'。
定义实例的方法:
实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数
class Person(object): def __init__(self, name): self.__name = name def get_name(self): return self.__name
定义类方法:
和属性类似,方法也分为实例方法和类方法,在class 中定义的全部是实例方法,实例方法的第一个参数是self本身。如下:@classmethod
class Person(object): sex='M' count=0 @classmethod def many(cls): return cls.count def __init__(self,name): self.name=name Person.count=Person.count+1print Person.many()p=Person('Jim')print Person.many()>>> 01>>>通过标记一个 @classmethod,该方法将绑定到 Person 类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.count 实际上相当于 Person.count。因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。
类的继承:
class Person(object): def __init__(self,name,sex): self.name=name self.sex=sexclass Student(Person): def __init__(self,name,sex,age): super(Student,self).__init__(name,sex) self.age=age p=Person('Jim','M')print p.names=Student('Tom','W',19)print s.name>>> JimTom>>>Python集成的特点:
总是从某一个类集成,默认继承object
调用super().__init__() 用来初始化父类
isinstance()判断类型
isinstance() 可以判断一个变量的类型,既可以用在python内置的数据类型又可以用在我们自己定义的类,本质上都是数据类型,拿上面的代码为例,判断:
print isinstance(p,Person)print isinstance(p,Student)print isinstance(s,Person)print isinstance(s,Student)>>>TrueFalseTrueTrue>>>
多态
类具有继承关系,并且子类类型可以向上转型做父类类型,我们在给Person,Student,Teacher,都加上toString()方法
class Person(object): def __init__(self,name,sex): self.name=name self.sex=sex def toString(self): return 'this is Person,person name is %s'%self.nameclass Student(Person): def __init__(self,name,sex,age): super(Student,self).__init__(name,sex) self.age=age def toString(self): return 'this is Studnet,student name is %s'%self.namedef f(x): print x.toString()p=Person('Jim','M')s=Student('Alice','W',19)f(p)f(s)>>> this is Person,person name is Jimthis is Studnet,student name is Alice>>>说明:子类和父类分别有自己的toString()方法,方法调用作用在实例的实际类型上,Student实际上拥有自己的toString()和来自父类的toString(),调用时总是先找到自己定义的toString(),如果找不到才会向上找,直到找到为止。
由于Python是动态语言,传递给f()的类型不一定是Person或者其子类,任何类型都可以。只要有一个toString()方法就可以,如下:
class Book(object): def toString(self): return 'book'def f(x): print x.toString()b=Book()f(b)>>>book>>>这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。
多重继承:
class A(object): def __init__(self, a): self.a = aclass B(A): def __init__(self, a): super(B, self).__init__(a) class C(A): def __init__(self, a): super(C, self).__init__(a) class D(B, C): def __init__(self, a): super(D, self).__init__(a)
像这样,D 同时继承自 B 和 C,也就是 D 拥有了 A、B、C 的全部功能。多重继承通过 super()调用__init__()方法时,A 虽然被继承了两次,但__init__()只调用一次
多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用。
例子:
+-Person
+- Student
+- Teacher
是一类继承树;
+- SkillMixin
+- BasketballMixin
+- FootballMixin
是一类继承树。
通过多重继承,请定义“会打篮球的学生”和“会踢足球的老师”。
class Person(object): passclass Student(Person): passclass Teacher(Person): passclass SkillMixin(object): passclass BasketballMixin(SkillMixin): def skill(self): return 'basketball'class FootballMixin(SkillMixin): def skill(self): return 'football'class BStudent(Student, BasketballMixin): passclass FTeacher(Teacher, FootballMixin): passs = BStudent()print s.skill()t = FTeacher()print t.skill()
获取对象信息:
type()
>>> type(123)<type 'int'>>>> s = Student('Bob', 'Male', 88)>>> type(s)<class '__main__.Student'>dir()
>>> dir(123) # 整数也有很多属性...['__abs__', '__add__', '__and__', '__class__', '__cmp__', ...]>>> dir(s)['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gender', 'name', 'score', 'whoAmI']dir()返回的属性是字符串列表,如果已知一个属性名称,要获取或者设置对象的属性,就需要用getattr()和 setattr( )函数了:
>>> getattr(s, 'name') # 获取name属性'Bob'>>> setattr(s, 'name', 'Adam') # 设置新的name属性>>> s.name'Adam'>>> getattr(s, 'age') # 获取age属性,但是属性不存在,报错:Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Student' object has no attribute 'age'>>> getattr(s, 'age', 20) # 获取age属性,如果属性不存在,就返回默认值20:20
特殊方法:
__str__:把一个类变成str
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __str__(self): return '(Person: %s, %s)' % (self.name, self.gender)>>> p = Person('Bob', 'male')>>> print p(Person: Bob, male)Python 定义了__str__()和__repr__()两种方法,__str__()用于显示给用户,而__repr__()用于显示给开发人员。
__cmp__:
对 int、str 等内置数据类型排序时,Python的 sorted() 按照默认的比较函数 cmp 排序,但是,如果对一组 Student 类的实例排序时,就必须提供我们自己的特殊方法__cmp__():
class Student(object): def __init__(self, name, score): self.name = name self.score = score def __str__(self): return '(%s: %s)' % (self.name, self.score) __repr__ = __str__ def __cmp__(self, s): if self.name < s.name: return -1 elif self.name > s.name: return 1 else: return 0上述 Student 类实现了__cmp__()方法,__cmp__用实例自身self和传入的实例 s 进行比较,如果 self 应该排在前面,就返回 -1,如果s 应该排在前面,就返回1,如果两者相当,返回 0。
__len__
如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。
要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。
class Students(object): def __init__(self, *args): self.names = args def __len__(self): return len(self.names)
斐波那契数列是由 0, 1, 1, 2, 3, 5, 8...构成。
请编写一个Fib类,Fib(10)表示数列的前10个元素,print Fib(10) 可以打印出数列的前 10 个元素,len(Fib(10))可以正确返回数列的个数10。
class Fib(object): def __init__(self, num): a, b, L = 0, 1, [] for n in range(num): L.append(a) a, b = b, a + b self.numbers = L def __str__(self): return str(self.numbers) __repr__ = __str__ def __len__(self): return len(self.numbers)f = Fib(10)print fprint len(f)
数学运算:
定义一个Rational 和加减乘除预算
def gcd(a, b): if b == 0: return a return gcd(b, a % b)class Rational(object): def __init__(self, p, q): self.p = p self.q = q def __add__(self, r): return Rational(self.p * r.q + self.q * r.p, self.q * r.q) def __sub__(self, r): return Rational(self.p * r.q - self.q * r.p, self.q * r.q) def __mul__(self, r): return Rational(self.p * r.p, self.q * r.q) def __div__(self, r): return Rational(self.p * r.q, self.q * r.p) def __str__(self): g = gcd(self.p, self.q) return '%s/%s' % (self.p / g, self.q / g) __repr__ = __str__r1 = Rational(1, 2)r2 = Rational(1, 4)print r1 + r2print r1 - r2print r1 * r2print r1 / r2>>>3/41/41/82/1>>>
类型转换:
Rational类实现了有理数运算,但是,如果要把结果转为 int 或 float 怎么办?要让int()函数正常工作,只需要实现特殊方法__int__():
class Rational(object): def __init__(self, p, q): self.p = p self.q = q def __int__(self): return self.p // self.q
__slots__
__slots__是指一个类允许的属性列表:__slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。
class Student(object): __slots__ = ('name', 'gender', 'score') def __init__(self, name, gender, score): self.name = name self.gender = gender self.score = score
__call__
一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。我们把 Person 类变成一个可调用对象:class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __call__(self, friend): print 'My name is %s...' % self.name print 'My friend is %s...' % friend
- Python进阶(三)
- Python进阶(三)Python语法
- python进阶(数据结构和算法[三])
- python学习笔记(三)--类进阶
- python--进阶三--SQLite
- Python进阶(三)——Python语法
- Python进阶(三)——Python语法
- Python进阶(三)——Python语法
- Python进阶(三)——Python语法
- python进阶三_函数
- python进阶学习笔记(三)数据库支持
- python进阶学习笔记(三)数据库支持
- python小白进阶三:主成分分析(PCA)
- python爬虫进阶(三):微博的抓取
- Python进阶(三):*args,**kwargs的使用
- javascript进阶(三)
- RequireJS进阶(三)
- (三)Mybatis进阶
- 6.时光机穿梭
- 如何在mac本上安装android sdk
- 《c primer plus》编程练习回顾-第十章
- 集中式vs分布式
- 2015-3-26C语言学习日记
- Python进阶(三)
- [Python]网络爬虫(12):爬虫框架Scrapy的第一个爬虫示例入门教程
- 6、NSNotificationCenter使用
- gcov 用法
- cocos3.4 改变窗口大小
- 7.版本回退
- 8.工作区和暂存区
- Dubbo抛出自定义异常
- Android ContextThemeWrapper解析