python3.x 基础七:面向对象进阶
类的高级方法:
1.静态方法:在类方法前增加关键字@staticmethod,将普通方法变成静态方法,不能再次传值,不能访问实例变量或者类变量,与类的关系仅仅是通过类名进行调用
2.类方法:在类方法前增加关键字@classmethod,类方法只能访问类变量,不能访问实例变量
3.属性方法:(重点)在类方法前增加关键字@property,调用的时候通过属性一样的方式访问(去掉括号调用),可以通过类私有属性加@setter重新赋值,@deleter删除私有属性后方能删除属性方法
- 静态方法:
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
obj1=Dog('hashiqi')
obj1.eat('baozi')
正常输出:hashiqi is eating baozi
增加关键字staticmethod:
class Dog(object):
def __init__(self,name):
self.name=name
@staticmethod
def eat(self,food):
print('%s is eating %s'%(self.name,food))
obj1=Dog('hashiqi')
obj1.eat('baozi')
报错:
Traceback (most recent call last):
File "D:/001python/01course/day07/static_method.py", line 11, in <module>
obj1.eat('baozi')
TypeError: eat() missing 1 required positional argument: 'food'
eat的实参没有传给self
结论:增加关键字@staticmethod后,类的方法变成了单纯的函数,无法访问类或者实例中的任何属性,仅增加类名进行调用
如果非要给静态方法传类属性,可以直接将对象传进去---没有意义:
class Dog(object):
def __init__(self,name):
self.name=name
@staticmethod
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat(obj1)
输出:hashiqi is eating
- 类方法 --关键字@classmethod
类方法无法访问实例属性
class Dog(object):
#name='yzw'
def __init__(self,name):
self.name=name
@classmethod
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat()
报错如下:
print('%s is eating '%(self.name))
AttributeError: type object 'Dog' has no attribute 'name'
类方法只能访问类属性:
class Dog(object):
name='yzw'
def __init__(self,name):
self.name=name
@classmethod
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat()
输入:yzw is eating
- 属性方法--关键字@property
无法正常使用调用方法
class Dog(object):
def __init__(self,name):
self.name=name
@property
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat()
报错如下:
obj1.eat()
TypeError: 'NoneType' object is not callable
改成调用属性的方法,也就是把括号去掉:
class Dog(object):
def __init__(self,name):
self.name=name
@property
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat
正常输出:hashiqi is eating
结论:把一个方法变成一个静态属性,无法通过()进行调用,它可以通过"对象.属性"进行调用
属性普通赋值也会报错:
class Dog(object):
def __init__(self,name):
self.name=name
@property
def eat(self):
print('%s is eating '%(self.name))
obj1=Dog('hashiqi')
obj1.eat
obj1.eat='value' error:
obj1.eat='value'
AttributeError: can't set attribute
结论:属性方法可以通过属性调用方式获取,但是不能直接给予赋值
通过特殊处理给属性方法传值:
再写一个同名的方法,使用@xxx.setter关键字进行赋值,但是怎么才能给属性里面的形参传值呢?
class Dog(object):
def __init__(self,name):
self.name=name
@property
def eat(self):
print('%s is eating '%(self.name))
@eat.setter
def eat(self,food):
print(food)
obj1=Dog('hashiqi') #正常实例化对象
obj1.eat # 调用属性方法
obj1.eat='value' #调用属性赋值方法 hashiqi is eating
value
属性传值二:
通过在构造方法里增加私有属性,给属性方法其他形参传值
class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
@property
def eat(self):
print('%s is eating'%self.name,self.__food)
@eat.setter
def eat(self,food):
print(food)
self.__food=food
d=Dog('hashiqi') # 1.正常实例化对象
d.eat # 2.正常调用属性方法 输出:hashiqi is eating None,此时self.__food的值取构造方法的初始值
d.eat='包子' # 3.通过setter属性赋值方法给方法赋值
d.eat # 4.再次调用属性方法,输出属性方法的结果,此时属性方法调用setter里设置的值 hashiqi is eating None
baozi
hashiqi is eating baozi
删除属性方法--无法删除:
class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
@property
def eat(self):
print('%s is eating %s '%(self.name,self.__food))
@eat.setter
def eat(self,food):
print(food)
self.__food=food
obj1=Dog('hashiqi')
obj1.eat
obj1.eat='baozi'
obj1.eat
del obj1.eat error
AttributeError: can't delete attribute
删除属性方法--先删除私有属性
class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
@property
def eat(self):
print('%s is eating %s '%(self.name,self.__food))
@eat.setter
def eat(self,food):
print(food)
self.__food=food
@eat.deleter
def eat(self):
del self.__food
print('had been deleted')
obj1=Dog('hashiqi')
obj1.eat
obj1.eat='baozi'
obj1.eat
del obj1.eat hashiqi is eating None
baozi
hashiqi is eating baozi
had been deleted
删除再进行调用报错:
class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
@property
def eat(self):
print('%s is eating %s '%(self.name,self.__food))
@eat.setter
def eat(self,food):
print(food)
self.__food=food
@eat.deleter
def eat(self):
del self.__food
print('had been deleted')
obj1=Dog('hashiqi')
obj1.eat
obj1.eat='baozi'
obj1.eat
del obj1.eat
obj1.eat # 依然是去调用静态方法,此时私有属性已被删除 error
print('%s is eating %s '%(self.name,self.__food))
AttributeError: 'Dog' object has no attribute '_Dog__food'
属性方法用途:隐藏细节,暴露简单接口给用户
案例:查询航空班次状态
1.调用航空公司API查询
2.对查询结果进行分析
3.将分析后的结果返回页面,用户不关心过程/方法,只关心状态,也就是属性方法的结果
class Flight(object):
def __init__(self,name):
self.fly_name=name
def checking_status(self):
print('checking flight %s status...'%self.fly_name)
return
@property
def Flight_status(self):
status=self.checking_status()
if status == :
print('flight had got canceled')
if status == :
print('flight is arrived')
if status == :
print('flight has departured already...')
if status == :
print('cannot confirm the flight status ... check later pls')
@Flight_status.setter
def Flight_status(self,status):
status_dict={:'canceled',:'arrived',:"departured"}
print('status has changed to %s'%status_dict.get(status))
fly1=Flight('A380')
fly1.Flight_status
fly1.Flight_status = output:
checking flight A380 status...
cannot confirm the flight status ... check later pls
status has changed to arrived
类的特殊成员方法
1.__doc__ 打印类下面的注释信息
class Class_name(object):
'''class description'''
pass
print(Class_name.__doc__) output:class description
2.__module__ 打印模块的名字 __class__ 打印类的名字
from fly import Flight
t=Flight('A380')
print(t.__module__)
print(t.__class__) output:
status has changed to arrived
fly
<class 'fly.Flight'>
3.__init__ 构造方法,实例化类的时候自动创建
4.__del__ 析构方法,一般不定义,系统会自动执行回收垃圾
5.__call__ 对象后面加括号,触发执行
class Dog(object):
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print(*args,**kwargs)
d1=Dog()
d1(1,2,3) output:
1 2 3
6.__dict__ 打印字典形式的类属性方法或者实例属性
class Dog(object):
address='earth'
def __init__(self,name,age):
self.name=name
self.age=age
def func1(self, *args, **kwargs):
print(*args,**kwargs)
print(Dog.__dict__) #以字典形式打印类的所有属性和方法
d1=Dog('hashiqi',19)
print(d1.__dict__) #以字典形式打印实例的属性
7.__str__ 如果一个勒种定义了__str__方法,那么打印对象的时候,默认输出该方法的返回值
class Dog(object):
address='earth'
def __init__(self,name,age):
self.name=name
self.age=age
def func1(self, *args, **kwargs):
print(*args,**kwargs)
def __str__(self): # 如果没有定义str方法,将打印对象的内存地址
return ('return value') d1=Dog('hashiqi',19)
print(d1) output:return value
8. item字典方法,使用起来像操纵字典,其实是类内置方法
class Dog(object):
def __getitem__(self, item):
print('getitem',item)
def __setitem__(self, key, value):
print('setitem',key,value)
def __delitem__(self, key):
print('delitem',key)
d1=Dog() # 1.实例化对象
value1=d1['key1'] # 2.调用getitem方法
d1['key2']='value2' # 3.调用setitem方法
del d1['key3'] # 4.调用delitem方法 output:
getitem key1
setitem key2 value2
delitem key3
类的本质
反射
- hasattr(obj,name_str) 判断一个对象里是否有对应的字符串方法
- getattr(obj,name_str)根据字符串去获取obj对象里对应的方法的内存地址
- setattr(obj,'y',z) 相当于与obj.y=z
- delattr
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self):
print('%s is eating...'%self.name) d1=Dog('hashiqi')
choice =input('input>>').strip() #判断有没有方法
print(hasattr(d1,choice)) #判断输入的字符串在内存地址中是否存在
print(getattr(d1,choice)) #获取内存地址,加括号直接调用
getattr(d1,choice)()
一般这么用:
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food)) d1=Dog('hashiqi')
choice =input('input>>').strip() #输入一个方法,如果方法在类中存在,则未true
if hasattr(d1,choice):
func=getattr(d1,choice) #增加一个变量,有助于传入参数
func('baozi') #将参数传给判断成功的方法 output:
input>>eat
hashiqi is eating baozi
动态装进取一个新方法:
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
def bulk(self):
print("%s is yelling"%self.name)
d1=Dog('hashiqi')
choice =input('input>>').strip() #输入一个方法,如果方法在类中存在,则未true
if hasattr(d1,choice):
func=getattr(d1,choice) #增加一个变量,有助于传入参数
func('baozi') #将参数传给判断成功的方法
else:
setattr(d1,choice,bulk)
d1.talk(d1) #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数 output:
input>>talk
hashiqi is yelling
动态装进去一个属性
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
def bulk(self):
print("%s is yelling"%self.name)
d1=Dog('hashiqi')
choice =input('input>>').strip() #输入一个方法,如果方法在类中存在,则未true
if hasattr(d1,choice):
func=getattr(d1,choice) #增加一个变量,有助于传入参数
func('baozi') #将参数传给判断成功的方法,如果输入一个已经存在的属性,则不能加括号调用
else:
# setattr(d1,choice,bulk)
# d1.talk(d1) #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数
setattr(d1,choice,2)
print(getattr(d1,choice)) output:
input>>asdf
2
删除一个属性
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
def bulk(self):
print("%s is yelling"%self.name)
d1=Dog('hashiqi')
choice =input('input>>').strip() #输入一个方法,如果方法在类中存在,则未true
if hasattr(d1,choice):
delattr(d1,choice)
else:
# setattr(d1,choice,bulk)
# d1.talk(d1) #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数
setattr(d1,choice,2)
print(getattr(d1,choice)) print(d1.name) output:
print(d1.name)
AttributeError: 'Dog' object has no attribute 'name'
再变化
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print('%s is eating %s'%(self.name,food))
def bulk(self):
print("%s is yelling"%self.name)
d1=Dog('hashiqi')
choice =input('input>>').strip() #输入一个方法,如果方法在类中存在,则未true
if hasattr(d1,choice):
getattr(d1,choice)
else:
setattr(d1,choice,bulk)
func = getattr(d1,choice) # 这里不管choice输入任何东西,都只调用bulk 就是把字符串choice反射成内存中bulk的地址
func(d1)
异常处理
try:
可能出错的语句
except 错误关键字1 as 别名: 别名捕获了错误的详细信息
处理语句
except 错误关键子2 as 别名:
处理语句
或者
except (错误关键字1,错误关键字2,。。。) as 别名:
多个错误无法定位
except Exception:
不管什么错误都放到这里,不建议一开始用
else:
如果except都没有捕捉到异常
就在这里处理
finally:
不管有没有出现错误,都会执行
自定义异常
class CustomException(Exception):
def __init__(self,msg):
self.msg=msg try:
raise CustomException('error') #这里实例化一个类了
except CustomException as e: # e保存的就是msg的值
print(e) output:
error
python3.x 基础七:面向对象进阶的更多相关文章
- 周末班:Python基础之面向对象进阶
面向对象进阶 类型判断 issubclass 首先,我们先看issubclass() 这个内置函数可以帮我们判断x类是否是y类型的子类. class Base: pass class Foo(Base ...
- Python之路【第六篇】python基础 之面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 和 issubclass(su ...
- Python基础之面向对象进阶二
一.__getattribute__ 我们一看见getattribute,就想起来前面学的getattr,好了,我们先回顾一下getattr的用法吧! class foo: def __init__( ...
- python基础_面向对象进阶
@property装饰器 之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效.我 ...
- 学习PYTHON之路, DAY 8 - PYTHON 基础 8 (面向对象进阶)
类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的 ...
- Python基础之面向对象进阶一
一.isinstance(obj,cls)和issubclass(sub,super) 1.isinstance(obj,cls)检查obj是否是类 cls 的对象 class A: pass obj ...
- 基础7 面向对象进阶与socket编程
1.静态方法(用得少)(解除某个函数跟类的关联,加了静态方法后,类便不能将类的参数传给静态方法函数了) class Dog(object): def __init__(self,name): @sta ...
- Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)
Python开发[第七篇]:面向对象 详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇) 上一篇<Python 面向对象(初级篇)> ...
- python基础——面向对象进阶下
python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...
随机推荐
- /proc/[pid]/status
http://man7.org/linux/man-pages/man5/proc.5.html /proc/[pid]/status Provides much of the information ...
- QT QLabel内容太长时候使用省略号
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/xiezhongyuan07/articl ...
- hexo-themes-setting
hexo-themes-setting hexotheme Hexo 主题配置管理 一半有几种方式, 可以删除git 单独维护 也可以使用 hexo 推荐的方式进行维护 所有需要写在主题配置文件中的配 ...
- 使用Spring Boot搭建你的第一个应用程序
文章目录 依赖配置 main程序配置 MVC配置 安全配置 存储 Web 页面和Controller 异常处理 测试 结论 Spring Boot是Spring平台的约定式的应用框架,使用Spring ...
- Element UI表格组件技巧:如何简洁实现跨页勾选、跨页统计功能
业务场景 在使用Element UI的Table组件时,常常面对这样的业务需求: 表格数据的每一项都要提供勾选框,当切换分页时,能够记忆所有页面勾选的数据,以实现批量提交不同页面勾选数据的功能.并且, ...
- SDN 是什么
SDN,Software Defined Network,软件定义(的)网络,这些年方兴未艾,愈演愈烈.但是,笔者以为,SDN 也有愈演愈劣的趋势.而且,现在业界关于什么叫 SDN,也是众说纷坛,莫衷 ...
- Java反射详细介绍
反射 目录介绍 1.反射概述 1.1 反射概述 1.2 获取class文件对象的三种方式 1.3 反射常用的方法介绍 1.4 反射的定义 1.5 反射的组成 1.6 反射的作用有哪些 2.反射的相关使 ...
- 小猪的Python学习之旅 —— 16.再尝Python数据分析:采集拉勾网数据分析Android就业行情...
一句话概括本文: 爬取拉钩Android职位相关数据,利用numpy,pandas和matplotlib对招人公司 情况和招聘要求进行数据分析. 引言: 在写完上一篇<浅尝Python数据分析: ...
- String(字符串) 比较大小 如果有A+B>B+A 则A>B
题目引入: 给定N个整数,那任意顺序排列连成一个数,得到的最大的数是多少? 分析:贪心,字典序排序,都不对大小比较也不对,今天我跟别人想了很久绞尽脑汁,各种模拟都失败了.最后才发现对于俩个数a=313 ...
- Mysql 远程连接错误排查
1. 测试本地与远程服务器端口能否连通 telnet 远程IP 端口号 telnet 192.168.1.1 3306 2.如果是在aliyun或者aws云服务器上自建数据库 2.1 在安全组里开 ...