Python 面向对象
面向对象
类和对象
Python类定义
类属性
类方法
面向过程和面向对象编程
- 面向过程编程:函数式编程,C程序等
- 面向对象编程:C++,Java,Python等
str. ->显示字符串的方法,属性
list. ->显示列表的方法,属性
tuple. ->显示元组的方法,属性
dict. ->显示字典的方法,属性
面向对象的主要思想是:
- 封装
- 继承
- 多态
这种思想方便解决较为复杂的项目,且维护起来较为容易。
-----------------------------------------
Python类定义
类定义:
类把需要的变量和函数组合成一起,这种包含称为“封装”
class A(object): 继承object这个类,跟C#一样,object是根对象
类的结构:
class 类名:
成员变量 – 属性
成员函数 – 方法
类名:每个单词首字母大写
函数名:第二个单词开始首字母大写
class MyClass(object):
def fun(self):
print "I am function"
类的方法中至少有一个参数self,self表示类本身
定义类有2种方法
一种是不加(object) class A():
一种是加(object) class A(object):
前者是传统的定义方法,后者是新的风格,建议使用后者,super这个内置函数只支持新风格定义的类,如果父类是旧风格定义的类,那么使用super来继承的时候就会报错。
报错:typeerror:super() argument 1 must be type,not classobj
##<span pycharm 使用指南Date:2016.08.12<span os sys string People(object): color = ' __age = 30 think(self): self.color = <span self.color self.color <span ren = People()ren.color = ' ren.colorren.think()__dict__' *30 People.color' *30__dict__
-----------------------------------------
对象的创建
创建对象的过程称之为实例化;当一个对象被创建后,包含三个方面的特性:对象句柄、属性和方法。
句柄用于区分不同的对象
对象的属性和方法与类中的成员变量和成员函数对应
obj = MyClass() //创建类的一个实例(对象)
通过对象来调用方法和属性
-----------------------------------------
类的属性
类的属性按使用范围分为公有属性和私有属性,类的属性范围取决于属性的名称。
- 公有属性:在类中和类外都能调用的属性。
公有属性可以不用实例化对象就可以访问,classname.attribute,类名.属性名 print People.color
People(object): color = ' (self): self.dwell = ' 公有属性pp=People()print pp.dwell
- 私有属性:不能在类外及被类以外的函数调用,子类也不能调用。 定义方式:以”__”双下划线开始的成员变量就是私有属性,可以通过instance._classname__attribute方式访问,print ren._People__age
实例化对象名._类名__私有属性名(实际不建议使用 实例化对象名._类名__私有属性名)
- 保护属性:在类中和子类都能调用的属性。
定义方式:以”_”单个下划线开始的成员变量就是保护属性,可以通过instance._attribute方式访问,print ren._age
- 内置属性:由系统在定义类的时候默认添加的,由前后双下划线构成,__dict__, __module__。
__dict__:打印出类的属性和方法
实例化对象.__dict__ :只能看到公有属性
类名.__dict__ :可以看到私有属性(实例化对象名._类名__私有属性名),公有属性,私有方法,公有方法,静态方法等等
静态属性和动态属性
实例化对象之后调用的属性是动态属性,可以修改属性值
ren = People()
ren.color = '白色人'
print ren.color
没有实例化对象用类名直接调用的属性是静态属性,不能修改
print People.color
-----------------------------------------
类的方法
方法的定义和函数一样,但是需要self作为第一个参数。
类方法为:
- 公有方法
- 私有方法
- 类方法
- 静态方法
- 内置方法
公有方法:在类中和类外都能调用的方法。
私有方法:不能被类的外部调用,在方法前面加上”__”双下划线就是私有方法。
self参数:用于区分函数和类的方法(必须有一个self),self参数表示执行对象本身。
内置方法:由系统在定义类的时候默认添加的,由前后双下划线构成,__str__(self), __init__(self)
类方法:被classmethod()函数处理过的函数,能被类名所调用,也能被对象所调用(是继承的关系)
classmethod(函数名)
classmethod(test) test是一个方法
def test(self):
print self.color
cm = classmethod(test)
People.cm()
静态方法:相当于”全局函数”,可以被类名直接调用,也可以用对象调用,可以被所有实例化对象共享,通过staticmethod()定义,静态方法没有”self”参数。
def test():
print People.color 访问类里面属性
sm = staticmethod(test)
People.sm()
装饰器:
- @classmethod
- @staticmethod
静态方法和动态方法
实例化对象之后调用的方法是动态方法,有一个例外,类方法classmethod(函数名)是动态方法,可以访问实例里的属性
没有实例化对象staticmethod() 直接调用的方法是静态方法
##<span pycharm 使用指南Date:2016.08.12<span MyClass(object): name=' (self): #构造函数 self.func1() self.() self.classFun() self.staticFun() func1(self): self.name, ' (self): self.name, @classmethod classFun(self): self.name, @staticmethod staticFun(): MyClass.name, mc=MyClass()MyClass.staticFun()mc.staticFun() #类方法和静态方法既可以实例对象调用又可以类名调用mc.classFun()MyClass.classFun()test 我是公有方法test 我是私有方法test 我是类方法test 我是静态方法test 我是静态方法test 我是静态方法test 我是类方法test 我是类方法
-----------------------------------------
Python内部类
在类的内部定义的类,主要目的是为了更好的抽象现实世界
内部类的实例化方法
方法1:直接使用外部类调用内部类
object_name = outclass_name.inclass_name()
方法2:先对外部类进行实例化,然后再实例化内部类
out_name = outclass_name()
in_name = out_name.inclass_name()
in_name.method()
--------------------------------------------------------
魔术方法/类内置方法
跟内置属性一样,类也有内置方法
__str__(self) :print 实例对象的时候会自动执行__str__(self)方法,并且__str__(self) 只能用return不能用print
People(object): color = ' __age = 30 (self): ' think(self): self.color = <span self.color self.color <span ren = People()ren.color = ' ren.colorprint ren
构造函数与析构函数
- 构造函数:
用于初始化类的内部状态,Python提供的构造函数是__init__();
__init__()方法是可选的,如果不提供,Python会给出一个默认的__init__方法
初始化传参
- 析构函数:
用于释放对象占用的资源,Python提供的析构函数是__del__();
__del__()也是可选的,如果不提供,则Python会在后台提供默认析构函数
(self): self.color=' (self): self.color='
-----------------------------------------
垃圾回收机制
Python采用垃圾回收机制来清理不再使用的对象;python提供gc模块释放不再使用的对象。
Python采用”引用计数”的算法方式来处理回收,即:当某个对象在其作用域内不再被其他对象引用的时候,python就自动清除对象;
gc模块的collect()函数可以一次性收集所有待处理的对象(gc.collect)
即使不调用析构函数释放资源也无所谓def __del__(self): ,python会利用垃圾回收机制回收垃圾
import gc
print gc.collect()
示例脚本
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc People(object): color = ' __age = 30 Chinese(object): name = <span (self): <span ): self.color = c self.think() self.fd = open() think(self): self.color = <span self.color <span __age (self): @classmethod test(self): @staticmethod test1(): <span (self): self.fd.close() gc.collect()jack = People() jack.color People.color'print gc.collect()
-----------------------------------------
类的继承
继承是面向对象的重要特性之一;
继承关系:继承是相对两个类而言的父子关系,子类继承了父类的所有公有属性和方法
继承实现了代码重用。
继承可以重用已经存在的数据和行为,减少代码的重复编写。
Python在类名后使用一对括号来表示继承关系,括号中的类即为父类。
class Myclass(ParentClass)
如果父类定义了__init__方法,子类可以调用父类的__init__方法也可以不调用
继承有两种方法:
1、super函数,建议使用super函数
super(子类类名, self).__init__('red') 父类的init函数
2、ParentClass.__init__(self, [args…])
如果子类需要扩展父类的行为,可以添加__init__方法的参数。
考虑一种情况
class A(object)
...
class B(A)
super(B, self).__init__('red')
或
A.__init__(self, 'red')
如果一旦B这个类改为继承C,那么就需要修改A.__init__(self, 'red')为C.__init__(self, 'red'),如果代码中
多处使用了继承,那么需要修改很多地方,所以建议使用super(B, self).__init__('red') ,即使修改为继承C,也不需要改代码
示例1
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc A: (self): <span <span B(A): (self): A.(self) b = B()#### leave B A: (self): <span <span B(A): (self): <span A.__init__(self) b = B()## leave B A: (self): <span <span B(A): b = B()### leave A
示例2
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc People(object): color = ' (self, c): self.color = c self.color think(self): self.color 只要实例化就会执行这个print,因为他不在任何方法里 Chinese(People): (self): super(Chinese, self).__init__('red') People.) think(self): cn = Chinese()cn.think()输出I am a thinkerInit...I am a redI like talking
super函数
super(子类类名, self).__init__('red') 父类的init函数
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc A(object): (self, c): <span c <span B(A): (self): super(B, self).) b = B()输出leave Aleave Benter Benter Ared
多重继承
object-》类A-》类B
Python支持多重继承,即一个类可以继承多个父类,可以使用父类的所有方法和属性;
语法:
class class_name(Parent_c1, Parent_c2,…)
注意:
当父类中出现多个自定义的__init__方法时,多重继承只执行第一个类的__init__方法,其他不执行。
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc People(object): color = ' (self): self.dwell = self.color = ' self.dwell self.color think(self): self.color self.dwell Martian(object): color = ' (self): self.dwell = ' self.dwell talk(self): <span Chinese(Martian, People): (self): People.(self)cn = Chinese()cn.think()cn.talk()输出EarthyellowI am a yellowMy home EarthI like talking{'}
-----------------------------------------
类的属性-总结
类属性,也是共有属性
类的私有属性
对象的共有属性
对象的私有属性
内置属性
函数的局部变量
全局变量
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc对象属性只能定义在方法内var6 = 不在类里面叫全局变量 MyClass(object): var1 = 类可以访问,对象也可以访问,类属性要在类里面或者说在类里面叫公有属性而不叫全局变量 ' func1(self): self.var3 = 只能对象访问 self. var5 = ' __var4 var5 func2(self): self.var1 __var2 self.var3 __var4 var6mc = MyClass()mc.func1() 要访问var3 这个对象公有属性要先执行一下func1这个方法 mc.var3mc1 = MyClass()print mc1.var3 #报错,因为mc1没有执行mc1.func1(),所以叫对象公有属性,因为是针对对象的不是针对类的mc.func1() 要访问var3 这个对象公有属性要先执行一下func1这个方法mc.func2()' * 50__dict__' * 50输出对象的私有属性 函数的局部变量 var5对象的公有属性 var3**************************************************对象的私有属性 函数的局部变量 var5类属性,类的公有属性 var1类的私有属性 对象的公有属性 var3对象的私有属性 全局变量 var6**************************************************{}**************************************************{': None}
类的方法-总结
公有方法
私有方法
类方法 --动态 @classmethod
静态方法 --静态 @staticmethod
内置方法
##<span pycharm 使用指南Date:2016.08.12<span os sys string gc MyClass(object): name = ' (self): self.func1() self.() self.classFun() 可以被类调用 也可以被对象调用 self.staticFun() 可以被类调用 也可以被对象调用 func1(self): self.name, <span self.__func2() (self): self.name, @classmethod classFun(self): self.name, @staticmethod 静态方法不能用self 使用类名来引用公有属性 mc = MyClass()输出Test 我是公有方法Test 我是私有方法Test 我是类方法Test 我是静态方法
函数/方法、类、模块的帮助 help函数
In [1]: help('aa'.strip())
no Python documentation found for 'aa'
需要把后面的括号去掉,即这样:help('aa'.strip)
如果带括号是看'aa'.strip()的返回结果帮助了 help('aa'.strip())。
所有看函数/方法、类、模块的帮助都不需要后面的括号。
查看一个模块的帮助
help('sys')
之后它回打开这个模块的帮助文档
查看一个数据类型的帮助
help('str')
返回字符串的方法及详细说明
a = [1,2,3]
help(a)
这时help(a)则会打开list的操作方法
help(a.append)
S.strip([chars]) -> string or unicode 去除前后的空格和换行符,制表符,\t \n
Return a copy of the string S with leading and trailing whitespace removed.
查看一个类的帮助的时候要看类的构造函数
p=subprocess.Popen(['dir'],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
help(p.communicate)
help(Popen)
Help on class Popen in module subprocess:
class Popen(__builtin__.object)
| Methods defined here:
|
| __del__(self, _maxint=2147483647)
|
iversal_newlines=False, startupinfo=None, creationflags=0)
| Create new Popen instance.
|
| communicate(self, input=None)
| Interact with process: Send data to stdin. Read data from
| stdout and stderr, until end-of-file is reached. Wait for
| process to terminate. The optional input argument should be a
| string to be sent to the child process, or None, if no data
| should be sent to the child.
|
| communicate() returns a tuple (stdout, stderr).
|
| kill = terminate(self)
|
| poll(self)
|
| send_signal(self, sig)
| Send a signal to the process
|
| terminate(self)
| Terminates the process
|
| wait(self)
| Wait for child process to terminate. Returns returncode
| attribute.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)