python学习笔记六 面向对象相关下(基础篇)
面向对象基本知识:
- 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用
- 类 是一个模板,模板中包装了多个“函数”供使用(可以将多函数中公用的变量封装到对象中)
- 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数
- 面向对象三大特性:封装、继承和多态
面向对象类成员
一、变量
变量包括:类变量和实例变量,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,
类变量:属于类
实例变量:属于实例
- class Role(object):
- #类变量,在内存中仅保存一份
- ac = None
- def __init__(self,name,role,weapon,life_value):
- #实例变量,保存在各个实例中
- self.name = name
- self.role = role
- self.weapon = weapon
- self.life_value = life_value
- def buy_gun(self,weapon):
- print("%s is buying [%s]" %(self.name,weapon))
- self.weapon = weapon
- p1 = Role("p1",'police','b12',)
- t1 = Role("t1",'tufei','b11',)
- t2 = Role("t2",'tufei','b13',)
- t3 = Role("t3",'tufei','b14',)
- #实例赋值,将创建新的变量给实例
- p1.ac = "China Brand"
- t1.ac = "US Brand"
- #类变量赋值,实例中没有创建该变量,继续使用类变量赋的值
- Role.ac = "JP Brand"
- print("p1:",p1.weapon,p1.ac)
- print("t1:",t1.weapon,t1.ac)
- print("t2:",t2.weapon,t2.ac)
- print("t3:",t3.weapon,t3.ac)
由上述代码可以看出【实例变量需要通过对象来访问】【类变量可以通过类访问】,在使用上可以看出类变量和实例变量的归属是不同的。其在内容的存储方式类似如下图:
由上图可知:
- 类变量在内存中只保存一份
- 实例变量在每个实例中都要保存一份
应用场景: 通过类创建实例时,如果每个对象都具有相同的变量,那么就使用类变量。
二、方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
- 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
- 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
- 静态方法:由类调用;无默认参数;
- class Foo:
- def __init__(self, name):
- self.name = name
- def ord_func(self):
- """ 定义普通方法,至少有一个self参数 """
- # print self.name
- print('普通方法')
- @classmethod
- #类方法,不能访问实例变量
- def class_func(cls):
- """ 定义类方法,至少有一个cls参数 """
- print('类方法')
- @staticmethod
- #静态方法,只是放在类下面,不能访问类和实例属性
- def static_func():
- """ 定义静态方法 ,无默认参数"""
- print('静态方法')
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同。
三、属性
如果你已经了解Python类中的方法,那么属性就非常简单了,因为Python中的属性其实是普通方法的变种。
对于属性,有以下三个知识点:
- 属性的基本使用
- 属性的两种定义方式
- class foo(object):
- def __init__(self,name):
- self.name = name
- self.num = None
- #属性,将普通方法变成属性
- @property
- def total_num(self):
- return self.num
- @total_num.setter
- def total_num(self,num):
- self.num = num
- print("total number is:",self.num)
- @total_num.deleter
- def total_num(self):
- print("total number got deleted")
- del self.num
#实例化- d = Animal("who")
- #调用属性
print(d.total_num)- #属性赋值
d.total_num =- #删除属性
del d.total_num- #报错num已经被删除
print(d.total_num)
由属性的定义和调用要注意一下几点:
- 定义时,在普通方法的基础上添加 @property 装饰器;
- 定义时,属性仅有一个self参数
- 调用时,无需括号
方法:obj.func()
属性:obj.total_num
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
四、类的私有化
类的所有成员都有两种形式:
- 公有成员,在任何地方都能访问
- 私有成员,只有在类的内部才能方法
定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)
- class Animal(object):
- def __init__(self, name):
- self.name = name #公有变量
- self.__num = None #私有变量
访问限制:只有在类的内部可以访问。。。
- class C(object):
- __name = "私有类变量"
- def func(self):
- print(C.__name)
- class D(C):
- def show(self):
- print(C.__name) #AttributeError: type object 'C' has no attribute '_D__name'
- #print(D.__name) #AttributeError: type object 'D' has no attribute '_D__name'
- C.__name #类访问,出错
- obj = C()
- obj.func() #类内部可以访问
- obj_son = D() #无法继承私有类属性
- obj_son.show() #派生类访问,出错
- class E(object):
- def __init__(self):
- self.__foo = "私有实例变量"
- def func(self):
- print(self.__foo) #类内部访问
- class F(E):
- def show(self):
- print(self.__foo) #派生类访问
- obj2 = E()
- obj2.__foo #通过对象直接访问,出错
- print(obj2._E__foo) #访问私有实例变量
- obj2.func() #类内部访问
- obj2_son = F()
- obj2_son.show() #派生类中访问,出错
- 方法、属性的访问于上述方式相似,即:私有成员只能在类内部使用,无法被继承
ps:非要访问私有属性的话,可以通过 对象._类__属性名- 五、类的特殊成员
- class foo(object):
- """
- __doc__显示类的描述信息
- """
- def __init__(self):
- """
- 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;
- """
- self.name = None
- self.age = None
- self.sq = []
- def __call__(self):
- """
- __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
- """
- print("__call__")
- def __str__(self):
- """
- 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
- :return:
- """
- return "啥"
- def __iter__(self):
- """
- 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
- """
- return iter(self.sq)
- def __del__(self):
- pass
- #def __new__(self):
- """
- __new__方法接受的参数虽然也是和__init__一样,但__init__是在类实例创建之后调用,而 __new__方法正是创建这个类实例的方法。
- 一般不用使用这个方法,否则你将无法实例化对象
- """
- #pass
#实例化对象- f = foo() #自动执行__init__方法
- f() #:对象() 或者 类()()调用__call__
- foo()() #调用call方法
- print(f.__doc__) #显示类的描述信息
- print(f.__dict__) #类或对象中的所有成员
- print(f) #方法输出__str__方法定义的返回值
- for i in f:print(i) #类型内部定义了 __iter__,可以迭代
- #test.py
import foo
obj = foo()
print(obj.__module__) # 表示当前操作的对象在那个模块
print(obj.__class__) # 表示当前操作的对象在那个类
print(isinstance(obj,foo))
__module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么

- class C:
- def __init__(self):
- self.name = 'wupeiqi'

- from lib.aa import C
- obj = C()
- print obj.__module__ # 输出 lib.aa,即:输出模块
- print obj.__class__ # 输出 lib.aa.C,即:输出类
__dict__
类或对象中的所有成员
上文中我们知道:类的普通字段属于对象;类中的静态字段和方法等属于类,即:
- class Province:
- country = 'China'
- def __init__(self, name, count):
- self.name = name
- self.count = count
- def func(self, *args, **kwargs):
- print 'func'
- # 获取类的成员,即:静态字段、方法、
- print Province.__dict__
- # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
- obj1 = Province('HeBei',)
- print obj1.__dict__
- # 获取 对象obj1 的成员
- # 输出:{'count': , 'name': 'HeBei'}
- obj2 = Province('HeNan', )
- print obj2.__dict__
- # 获取 对象obj1 的成员
- # 输出:{'count': , 'name': 'HeNan'}
__dict__
__iter__
用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
- class Foo(object):
- pass
- obj = Foo()
- for i in obj:
- print i
- # 报错:TypeError: 'Foo' object is not iterable
第一步
- #!/usr/bin/env python
- # -*- coding:utf- -*-
- class Foo(object):
- def __iter__(self):
- pass
- obj = Foo()
- for i in obj:
- print i
- # 报错:TypeError: iter() returned non-iterator of type 'NoneType'
第二步
- #!/usr/bin/env python
- # -*- coding:utf- -*-
- class Foo(object):
- def __init__(self, sq):
- self.sq = sq
- def __iter__(self):
- return iter(self.sq)
- obj = Foo([,,,])
- for i in obj:
- print i
第三步
- 以上步骤可以看出,for循环迭代的其实是 iter([11,22,33,44]) ,所以执行流程可以变更为
#!/usr/bin/env python- # -*- coding:utf- -*-
- obj = iter([,,,])
- for i in obj:
- print i
六、反射
python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,这四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
- class Foo(object):
- def __init__(self):
- self.name = 'wupeiqi'
- def func(self):
- return 'func'
- obj = Foo()
- # #### 检查是否含有成员 ####
- hasattr(obj, 'name')
- hasattr(obj, 'func')
- # #### 获取成员 ####
- getattr(obj, 'name')
- getattr(obj, 'func')
- # #### 设置成员 ####
- setattr(obj, 'age', )
- setattr(obj, 'show', lambda num: num + )
- # #### 删除成员 ####
- delattr(obj, 'name')
- delattr(obj, 'func')
- 反射实例
- import sys
- class Webserver(object):
- def __init__(self,host,port):
- self.host = host
- self.port = port
- def start(self):
- print("Server is starting...")
- def stop(self):
- print("Server is stopping...")
- def restart(self):
- self.stop()
- self.start()
- #def test_run(name):
- # print("test running...",name)
- def test_run(self,name): #定义函数,setter添加该函数至实例方法
- print("test running...",name,self.host)
- if __name__ == "__main__":
- server = Webserver("1.1.1.1",)
- server2 = Webserver("2.2.2.2",)
- #第三种实现 反射
- if hasattr(server,sys.argv[]): #判断sys.argv[]是否在对象server中
- func = getattr(server,sys.argv[]) #获取server.method内存地址
- func() #执行server.method()
- setattr(server,"run",test_run) #在该实例 server 中,添加方法 run 方法名,test_run 函数,无法为方法自动传入self
- #server.run("koka") #执行添加不带self参数的test_run,无法调用实例变量
- server.run(server,"koka") #执行添加self参数的test_run,调用的时候需要手动添加实例
- setattr(server,"root","koka") #该在实例中添加变量,同上
- print(server.root) #调用实例变量
- #print(server2.root) #其他实例无法调用
- delattr(Webserver,'start') #删除类中的start方法
- print(server.restart())
- """
- 判断用户输入是否存在实例
- #第一种实现 一个一个输出匹配
- if sys.argv[] == "start":
- 执行server.start()
- #第二种实现 定义字典查找
- cmd_dic ={
- "start":server.start,
- "stop":server.stop
- }
- if sys.argv[] in cmd_dic:
- cmd_dic[sys.argv[]]()
- """
结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!
更多内容请参考:http://www.cnblogs.com/wupeiqi/articles/5017742.html
七、异常处理
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!
- try:
- pass
- except Exception,ex:
- pass
- 常用的内建异常类
- Exception 所有异常类的基类
- AttributeError 特性引用或赋值失败时引发
- IOError 试图打开不存在文件(报或其他情况)时引发
- IndexError 在使用序列中不存在的索引时引发
- KeyError 在使用映射中不存在的键是引发
- NameError 在找不到名字(变量)时引发
- SyntaxError 在代码为错误形式时引发
- TypeError 在内建操作或者函数应用于错误类型的对象时引发
- ValueError 在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发
- ZeroDivisionError 在除法或者模除操作的第二个参数为0时引发
万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:
- try:
- s = input('Enter something --> ')
- except EOFError:
- print('\nWhy did you do an EOF on me?')
- sys.exit() # exit the program
- except Exception: # 对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行
- print('\nSome error/exception occurred.')
- # here, we are not exiting the program
- s1 = 'hello'
- try:
- int(s1)
- except KeyError as e:
- print('键错误')
- except IndexError as e:
- print('索引错误')
- except Exception as e:
- print('错误')
- try:
- f = open('poem.txt')
- while True: # our usual file-reading idiom
- line = f.readline()
- if len(line) == :
- break
- time.sleep()
- print(line)
- finally:
- f.close()
- print('Cleaning up...closed the file')
- class MyException(Exception):
- pass
- try:
- print("normal code here")
- except MyException:
- print("MyException encoutered")
- else:
- print "No exception”
- class MyException(Exception):
- pass
- try:
- #some code here
- raise MyException
- except MyException:
- print("MyException encoutered")
python学习笔记六 面向对象相关下(基础篇)的更多相关文章
- Python学习笔记整理总结【语言基础篇】
一.变量赋值及命名规则① 声明一个变量及赋值 #!/usr/bin/env python # -*- coding:utf-8 -*- # _author_soloLi name1="sol ...
- python学习笔记五 模块上(基础篇)
模块学习 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
- python学习笔记三 文件操作(基础篇)
文件操作 打开文件 open(name[,mode[,buffering]]) open函数使用一个文件名作为强制参数,然后返回一个文件对象.[python 3.5 把file()删除掉] w ...
- Python学习笔记六
Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...
- Python学习笔记(一):基础知识
一.什么是python? python是一种面向对象.解释型的计算机语言,它的特点是语法简洁.优雅.简单易学 二.编译型语言和解释型语言 编译型语言就是把程序编译成计算机语言然后执行,(一次编译到处运 ...
- python学习笔记——多进程间通信——Linux信号基础
1 信号的基本描述 Signal信号(其全程为软中断信号)是Linux系统编程中非常重要的概念,信号是异步进程中通信的一种方式. 作用是通知进程发生了异步事件.进程之间可以调用系统来传递信号, 本身内 ...
- python学习笔记六 初识面向对象上(基础篇)
python面向对象 面向对象编程(Object-Oriented Programming )介绍 对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,虽然大家都知道OOP的三大特性 ...
- python学习笔记(10):面向对象
一.类和实例 1.类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 2.对象:通过类定义的数据结构实例.对象包括两个数据成员( ...
- python学习笔记(7): 面向对象
class Foo: #类中的函数 def bar(self): #功能阐述 print('Bar') pass def hello(self,name): print('i am %s' %name ...
随机推荐
- Sql Server按树形结构排序查询表记录
http://blog.csdn.net/dxnn520/article/details/8089149 ----------------------------------------------- ...
- 了解C++默认编写并调用哪些函数
概念:编译器可以暗自为class创建default构造函数.copy构造函数.copy assignmengt构造函数,以及析构函数. 比如你写下:struct Node { }; 这就好像你写下这样 ...
- 使用putty组件向服务器上传或下载文件
基于SSH的连接 上传文件: pscp -P 28661(portNum) -pw password sourceFilePath user@serverIP:destinationFilePath ...
- MATLAB中提供的线型属性
MATLAB中提供的线型属性有: 线型 说明 标记符 说明 颜色 说明 - 实线(默认) + 加号符 r 红色 -- 双划线 o 空心圆 g 绿色 : 虚线 * 星号 b 蓝色 :. 点划线 . 实心 ...
- Careercup | Chapter 8
8.2 Imagine you have a call center with three levels of employees: respondent, manager, and director ...
- Empire C:Basic 1
一.首先,从一个C程序开始: ///Name:Hello World ///Author:JA ///Date:2015-2-4 #include <stdio.h> //包含标准库的信息 ...
- Codeigniter 3.0 相关文档 part one
分页配置项 http://stackoverflow.com/questions/18418900/codeigniter-pagination-config-without-repeating-wi ...
- iOS 3D touch 使用技巧
第一个 在桌面中3d Touch 打开菜单 由于本人纯属代码党,本次实现方法也只使用代码实现 到达到这个效果并不难,只需要在appdelegate中实现以下代码即可 ,当然也有缺点,就是这个app没运 ...
- LightOj 1236 - Pairs Forming LCM (分解素因子,LCM )
题目链接:http://lightoj.com/volume_showproblem.php?problem=1236 题意:给你一个数n,求有多少对(i, j)满足 LCM(i, j) = n, ...
- 部署移动BI必须要考虑的五大因素
随着大屏智能手机和平板电脑的普及,商业智能分析应用程序也需要移动化.由于用户并不会长时间在办公桌前工作.在新的设备以及新的用户的共同促进下,移动BI即将成为主流. 但是,所有人都应该清楚这样一个事实: ...