Python全栈开发之7、面向对象编程进阶-类属性和方法、异常处理和反射
一、类的属性
1、@property属性
作用就是通过@property把一个方法变成一个静态属性
class Room: def __init__(self,name,length,width,height):
self.name=name
self.length=length
self.width=width
self.height=height @property
def cal_area(self): return self.length*self.width r1=Room("room1",100,100,100)
print(r1.cal_area)
class Flight(object):
def __init__(self,name):
self.name=name def checking_status(self): print("checking flight %s status"%self.name) return 1 @property
def flight_status(self): status=self.checking_status()
if status==0:
print("flight has canceled")
elif status==1:
print("flight has arrived")
else:
print("cannot confirm the flight status...,please check later") @flight_status.setter # 修改属性
def flight_status(self, status):
status_dic = {
0: "canceled",
1: "arrived",
2: "departured"
} print("\033[31;1mHas changed the flight status to \033[0m", status_dic.get(status)) f=Flight("东方航空") f.flight_status
f.flight_status=2
示例
二、类的方法
1、类方法@classmethod
供类使用的方法,类级别调用
class Room:
tag="一居室"
def __init__(self,name,length,width,height):
self.name=name
self.length=length
self.width=width
self.height=height @classmethod
def roomInfo(cls): #cls是自动生成的,类方法只能访问类变量,不能访问实例变量
print(cls.tag) Room.roomInfo() #通过类直接调用
2、静态方法 @staticmethod
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法.
普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法
class Dog(object): def __init__(self,name):
self.name=name @staticmethod # 静态方法跟类没什么关系 相当于普通函数
def eat(name,food): # 把eat方法变为静态方法
print("%s is eating %s"%(name,food)) Dog.eat('alex',"面包")
class Dog(object): def __init__(self,name):
self.name=name @staticmethod #静态方法跟类没什么关系 相当于普通函数
def eat(self): #把eat方法变为静态方法 print("%s is eating food"%self.name) d=Dog("xiaoming")
d.eat() #这样调用会报错
报错如下:说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
Traceback (most recent call last):
File "D:/python/day7/静态方法.py", line 23, in <module>
d.eat()
TypeError: eat() missing 1 required positional argument: 'self'
想让上面的代码可以正常工作有两种办法
1. 调用时主动传递实例本身给eat方法,即d.eat(d)
class Dog(object): def __init__(self,name):
self.name=name @staticmethod
def eat(self): print("%s is eating food"%self.name) d=Dog("xiaoming")
d.eat(d) #这样调用 或者Dog.eat(d)
在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了
三、isinstance(obj,cls)和issubclass(sub,super)
class Foo:
pass f1=Foo() #判断一个对象是否是一个类的实例
print(isinstance(f1,Foo))
# 返回 True
isinstance(obj,cls)判断一个对象是否是一个类的实例
class Foo:
pass class Bar(Foo):
pass # 判断一个类是否是另一个类的子类
print(issubclass(Bar,Foo))
# 返回 True
issubclass(sub,super)判断一个类是否是另一个类的子类
四、类的特殊成员方法
1.__doc__ 方法
class Foo:
""" 描述类信息 """ def func(self):
pass print (Foo.__doc__)
#输出:描述类信息
__doc__方法:类的文档描述信息
2.__module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
3. __init__ 构造方法,通过类创建对象时,自动触发执行
4. __del__ : 析构方法,当对象在内存中被释放时,自动触发执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,
所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
5. __call__ 方法 : 对象后面加括号,触发执行
class Dog(object): def __init__(self, name):
self.name = name def __call__(self, *args, **kwargs):
print(args, kwargs) d = Dog("Jim") d() # 对象加括号() 就执行__call__方法
__call__()方法
6. __dict__ 查看类或对象中的所有成员
7. __str__ :如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值
class Dog(object): name='jim' def __init__(self,name):
self.name=name def __str__(self): return "__str_" d=Dog("Jim") print(d) #打印对象时 输出__str__方法的返回值而非内存地址
__str__()方法
6. __new__和 __metaclass__方法
class Foo(object): def __init__(self,name):
self.name=name def __str__(self): return self.name f=Foo("xiaoming") print(f)
print(type(f))
print(type(Foo)) #Foo()类也是由type类实例化产生 输出:
xiaoming
<class '__main__.Foo'>
<class 'type'>
上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
五、反射
主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
1、hasattr()方法
hasattr(object, name) 判断object中有没有一个name字符串对应的方法或属性
2、getattr()方法
getattr(object, name, default=None) 去object对象中获取name成员内存地址
3、setattr()方法
def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass
# setattr是给一个对象添加一个新的属性或方法
4、delattr()方法
def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y''
"""
pass
def talk(self):
print("%s is talking"%self.name) class Dog(object):
def __init__(self,name):
self.name=name def eat(self): print("%s is eating .."%self.name) d=Dog("哈巴狗") choice=input(">>:").strip()
#
# print(hasattr(d,choice)) #反射 hasattr 判断一个对象里是否有对应的字符串的属性方法映射
#
# print(getattr(d,choice)) #相当于print(d.eat) 得到eat的内存地址
#
# func=getattr(d,choice) #根据字符串去获取obj对象里的对应的方法的内存地址,没有就会报错
# func() setattr(d,'age',18) # 给对象设置一个属性
print(d.__dict__) # 查看d的属性 setattr(d,choice,talk) #设置一个函数属性,相当于d.choice=talk 把talk的内存地址赋给了对象d.choice
setattr(d,"func1",lambda x:x+1) func=getattr(d,choice)
print(d.__dict__)
func(d) delattr(d,choice) # 删除属性
示例
5、__getattr__()方法和__getattrbute__()方法
class FileHander: def __init__(self,filename,mode='r',encoding="utf-8"):
print(mode)
self.file=open(filename,mode=mode,encoding=encoding) def __getattr__(self, item): return getattr(self.file,item) f1=FileHander("a.txt",'a+') f1.write("")
f1.seek(0)
data=f1.read() print(data)
__getattr__()没有属性就会调用该方法
class Foo:
def __init__(self,age): self.age=age def __getattr__(self, item): print("执行的是getattr") def __getattribute__(self, item):
print("执行的是getattrbute") f1=Foo(18)
print(f1.name) # 访问不存在的属性,如果没有__getattrbute__()方法,会触发__getattr__()方法
print(f1.age) # 否则有或者没有该属性都会触发__getattrbute__()方法
__getattrbute__()方法
6、__getitem__()和__setitem__()、__delitem__()方法
class Foo: def __init__(self,age):
self.age=age def __getitem__(self, item): print("get item")
return self.__dict__[item]
def __setitem__(self, key, value): self.__dict__[key]=value
print("set item") def __delitem__(self, key):
self.__dict__.pop(key)
print("del item") f1=Foo(18) f1['name']="allen" print(f1.__dict__) print(f1['name'])
print(f1.name)
print(f1['age'])
del f1['name']
方法示例--中括号方式操作属性
7、__format__()方法
date_format_dict={'ymd':"{0.year}-{0.month}-{0.day}",
'm-d-y':"{0.month}-{0.year}-{0.day}",
'y:m:d':"{0.year}:{0.month}:{0.day}"} class Date:
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day def __format__(self, format_spec): if not format_spec or format_spec not in date_format_dict:
format_spec="ymd"
fm=date_format_dict[format_spec]
return fm.format(self) d=Date(2019,11,18) # x="{0.year}-{0.month}-{0.day}".format(d)
# print(x) print(format(d))
print(format(d,'y:m:d'))
__format__(self, format_spec)方法
六、异常处理
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是显示一个提示的页面,通俗来说就是不让用户看见大黄页!!!
names=['jim','lucy']
data={}
print(type(data))
s1='hello' try: #异常处理
#open('t.txt')
# data['name']
int(s1)
names[2] # except IndexError as e :
# print("no names[2]",e)
#
# except KeyError as k:
# print("key error",k) except ValueError as e: #python3 用as python2.6 用
print(e) except Exception as e: #抓住所有异常错误
print("出错了",e) else:
print("一切正常") finally:
print("不管有没有错,都执行")
python3 用as python2.6 用 , except ValueError , e:
异常种类
python中的异常种类非常多,每个异常专门用于处理某一项异常!!!
常用异常:
AttributeError #试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError #输入/输出异常;基本上是无法打开文件
ImportError #无法引入模块或包;基本上是路径问题或名称错误
IndentationError #语法错误(的子类) ;代码没有正确对齐
IndexError #下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError #试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C#被按下
NameError #使用一个还未被赋予对象的变量
SyntaxError #Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError #传入对象类型与要求的不符合
UnboundLocalError# 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError #传入一个调用者不期望的值,即使值的类型是正确的
更多异常:
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
在python的异常中,有一个万能异常:Exception,他可以捕获任意异常
自定义异常
class TestExceptipon(Exception):
def __init__(self,msg):
self.msg=msg def __str__(self): return 'asdasd' try:
raise TestExceptipon('我的异常') #触发自己写的异常 except TestExceptipon as e:
print(e)
动态导入模块
import importlib #动态导入模块 aa=importlib.import_module("lib.aa") #aa为lib文件下的一个模块 #复制给aa aa.test() 调aa模块里面的test()函数 print(aa.name)
assert断言
import importlib lib=importlib.import_module("lib.aa") lib.test() print(lib.name) assert type(lib.name) is str #断言lib.name是一个字符串就往下执行 print('ok') print("okkk")
Python全栈开发之7、面向对象编程进阶-类属性和方法、异常处理和反射的更多相关文章
- 战争热诚的python全栈开发之路
从学习python开始,一直是自己摸索,但是时间不等人啊,所以自己为了节省时间,决定报个班系统学习,下面整理的文章都是自己学习后,认为重要的需要弄懂的知识点,做出链接,一方面是为了自己找的话方便,一方 ...
- python全栈开发之路
一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...
- python全栈开发之OS模块的总结
OS模块 1. os.name() 获取当前的系统 2.os.getcwd #获取当前的工作目录 import os cwd=os.getcwd() # dir=os.listdi ...
- Python全栈开发之9、面向对象、元类以及单例
前面一系列博文讲解的都是面向过程的编程,如今是时候来一波面向对象的讲解了 一.简介 面向对象编程是一种编程方式,使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” ...
- Python全栈开发之6、面向对象
一.创建类和对象 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例 ...
- Python全栈开发之14、Javascript
一.简介 前面我们学习了html和css,但是我们写的网页不能动起来,如果我们需要网页出现各种效果,那么我们就要学习一门新的语言了,那就是JavaScript,JavaScript是世界上最流行的脚本 ...
- Python全栈开发之1、输入输出与流程控制
Python简介 python是吉多·范罗苏姆发明的一种面向对象的脚本语言,可能有些人不知道面向对象和脚本具体是什么意思,但是对于一个初学者来说,现在并不需要明白.大家都知道,当下全栈工程师的概念很火 ...
- Python全栈开发之MySQL(二)------navicate和python操作MySQL
一:Navicate的安装 1.什么是navicate? Navicat是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设.它的设计符合数据库管理员.开发人员及中小 ...
- Python全栈开发之2、数据类型-数值、字符串、列表、字典、元组和文件处理
一.Python 运算符 1.算术运算: 2.比较运算: 3.赋值运算: 4.逻辑运算: 5.成员运算: 二.基本数据类型 1.数字整型 int(整型) 在32位机器上,整数的位数为32位,取值范围为 ...
随机推荐
- P2502 [HAOI2006]旅行 最小生成树
思路:枚举边集,最小生成树 提交:1次 题解:枚举最长边,添加较小边. #include<cstdio> #include<iostream> #include<algo ...
- 洛谷 P1355 神秘大三角(计算几何基础)
P1355 神秘大三角 题目提供者yeszy 标签 福建省历届夏令营 难度 普及/提高- 题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三 ...
- python实现 单链表的翻转
#!/usr/bin/env python #coding = utf-8 class Node: def __init__(self,data=None,next = None): self.dat ...
- ffmpeg编码h264设置规格
ffmpeg -i demo.ts -profile:v baseline -vcodec h264 -acodec aac -f flv demo.flv
- LSTM参数和结构的本质理解——num_units参数/batch_size/cell计算
参考 ———— 图例讲解 https://blog.csdn.net/u014518506/article/details/80445283 理解:cell其实只有一个 : sequence leng ...
- MySQL Cluster 集群部署
前言 此篇博客用以介绍 MySQL Cluster 集群部署方法 一.节点规划 序号 IP地址 节点名称 1 172.16.1.201 mysql-manage 2 172.16.1.202 mysq ...
- Rocketmq同步发送消息
package com.bfxy.rocketmq.quickstart; import org.apache.rocketmq.client.exception.MQBrokerException; ...
- MS SQL 数据类型转换
MS SQL 转换数据类型 select cast(列A as int) 列A select convert(int,列A) 列A --转字符串为int select len(ltrim(str('数 ...
- 快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题
快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题 转 https://www.jb51.net/article/144939.htm 今天小编就为大家分享一篇快速解决设置And ...
- 在react项目中启用mobx的配置方法
1.安装插件 npm install --save-dev babel-preset-mobx mobx mobx-react 2.package.json配置 "dependencies& ...