Python 面向对象编程之进阶使用
我们在https://www.cnblogs.com/yinsedeyinse/p/9976280.html中学习了面向对象的编程方法。现在学习他的进阶用法。
1. 静态方法
2. 类方法
3. 属性方法
4. 类的特殊功能方法
静态方法、类方法以及属性方法:我们先定义一个类,在类里定义一个方法
class Person(object):
def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating %s"%(self.name,food)) peaple = Person("Jack")
peaple.eat("cake")
Jack is eating cake
运行结果
这个是常规的类的使用,一切正常,
然后我们把方法前加一个@staticmethod,把eat()转变成一个静态方法,运行一下,程序报错了!
TypeError: eat() missing 1 required positional argument: 'food'
运行结果
发现少了个参数,我们把程序简化一下,看看是怎么回事!
class Person(object):
def __init__(self,name):
self.name = name
self.__food = None
@staticmethod
def eat(self):
print(self.name)
peaple = Person("Jack")
peaple.eat()
TypeError: eat() missing 1 required positional argument: 'self'
运行结果
再改一下
class Person(object):
def __init__(self,name):
self.name = name
self.__food = None
@staticmethod
def eat(name,food):
print("%s is eating %s"%(name,food))
peaple = Person("Jack")
peaple.eat("David","cake")
David is eating cake
运行结果
可以发现,静态方法无法调用类里的属性了!
所以,静态方法就是实际上已经跟类没什么关系了,也就是名义上归类管理。在方法内无法调用类或实例里的任何属性。还有个用法相当于类的工具包(高级语法,有机会再说!)。
我们再看看类方法,在方法前加上@classmethod运行一下
class Person(object):
def __init__(self,name):
self.name = name
@classmethod #类方法
def eat(self,food):
print("%s is eating %s"%(self.name,food))
peaple = Person("Jack")
peaple.eat("cake")
AttributeError: type object 'Person' has no attribute 'name'
运行结果
提示没有“name”的变量,为什么呢?我们把name定义成类变量试一试。
class Person(object):
name = "Jeff"
def __init__(self,name):
self.name = name
@classmethod
def eat(self,food):
print("%s is eating %s"%(self.name,food))
peaple = Person("Jack")
peaple.eat("cake")
Jeff is eating cake
运行结果
类变量只能访问类变量,不能访问实例变量。
属性方法
class Person(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print("%s is eating"%self.name)
p1 = Person("Jack")
p1.eat #这里的p1.eat调用的是属性,不是方法
Jack is eating
运行结果
在这个方法前加了@property,就把原来的方法改成了属性方法。在实例化后,不能用访问方法的形式(p1.eat())去访问,而要用属性的形式(p1.eat)。
但是有个问题,如果在属性方法里有参数需要传递的话,就要用到装饰器了!
class Person(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("set to food:",food)
self.__food = food
p1 = Person("Jack")
p1.eat
p1.eat = "bread" #对属性方法赋值
p1.eat
Jack is eating None
set to food: bread
Jack is eating bread
运行结果
完成效果,如果我们想把属性方法删除,用一般的删除方法是不行的
del p1.eat
这时候我们必须在类里重新定义个方法
class Person(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("set to food:",food)
self.__food = food
@eat.deleter #删除方法
def eat(self):
del self.__food
print("已删除!")
p1 = Person("Jack")
p1.eat
p1.eat = "bread" #对属性方法赋值
p1.eat
del p1.eat #删除属性方法
p1.eat #重新调用测试一下
Jack is eating None
set to food: bread
Jack is eating bread
已删除!
Traceback (most recent call last):
File "D:/python/week7/属性方法.py", line 45, in <module>
p1.eat
File "D:/python/week7/属性方法.py", line 31, in eat
print("%s is eating %s"%(self.name,self.__food))
AttributeError: 'Person' object has no attribute '_Person__food'
运行结果
那有什么用呢?几个例子,航空公司都能提供航班状态,而其他的三方运营商需要调用这个值,显而易见的是运营商不能修改航班状态
class Flight(object):
def __init__(self,name):
self.name = name def checking_status(self):
print("checking flight %s status"%self.name)
@property
def flight_status(self):
status = self.checking_status()
if status == 0:
print("flight is caceled!")
elif status == 1:
print("flight is arrived!")
elif status == 2:
print("flight has departured already!")
else:
print("cannot confirm the flight status,please check later!") @flight_status.setter #航空公司返回航班的状态关键字
def flight_status(self,status):
status_dic = {
0:'caceled',
1:'arrived',
2:'departured'
} @flight_status.deleter #删除该航班状态
def flight_status(self):
print("status is deleted!")
f = Flight("MU2388") #要查的航班编号
f.flight_status = 1 #航空公司每次只返回一个值描述出该航班状态
f.flight_status #其他的运营商直接访问属性的值,而不能改变其状态
现在来看一看一些类的特殊方法:
1.__doc__ 获取类的描述信息
# Author:Aaron
class People():
'''
该类描述了人类
'''
def func1(self):
pass
print(People.__doc__)
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/类的特殊成员.py
该类描述了人类
运行结果
在对类进行描述时,只能用‘’‘——’‘’来注释,用#注释时返回值为None。并且__doc__可以在不进行实例化时直接对类使用,也可以对实例使用。
2.__module__和__class__
from lib.aa import C
obj = C()
print(obj.__module__) #输出lib.aa,即为输出该功能所属模块
print(obj.__class__) #输出lib.aa.C,即为输出该类
在大量调用模块时,用这两个方法可以显示调用的类是属于那个模块的。
3.__call__
在实例后加(),执行功能
class Dog():
def __call__(self, *args, **kwargs):
print("__call__的用法")
d1 = Dog()
d1()
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/类的特殊成员.py
__call__的用法
运行结果
在功能中,可以传递各种参数。
4.__dict__查看类或对象中的所有成员
class People():
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def eat(self):
pass
def talk(self):
pass p1= People("Jack",22,"male")
print(p1.__dict__) #打印所有实例属性,不包括类属性
print(People.__dict__) #打印所有类属性,不包括实例属性
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/类的特殊成员.py
{'name': 'Jack', 'age': 22, 'sex': 'male'}
{'__module__': '__main__', '__init__': <function People.__init__ at 0x00000243C1246510>, 'eat': <function People.eat at 0x00000243C1246598>, 'talk': <function People.talk at 0x00000243C1246620>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
运行结果
以一个字典的形式把类或实例的方法打印出来,作用是在程序运行以后,如果有新加的属性,可以用这个方式查看。
5.__str__ 可以直接用print打印字符串
class People():
def __init__(self,name):
self.name = name
def __str__(self):
return 'obj:%s'%self.name p = People('Jeck')
print(p)
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/类的特殊成员.py
obj:Jeck
运行结果
django中常用的用法,可以用来返回实例。
6. __getitem__,__setitem__,__delitem__
可以把一个字典封装成一个实例(类),用字典的方式添加类的属性等。然后控制字典的权限。用户可以访问这个字典其实是访问了一个类,但可以对用户进行权限控制。
Python 面向对象编程之进阶使用的更多相关文章
- python面向对象编程之组合
前面讲了面向类与对象的继承,知道了继承是一种什么"是"什么的关系. 然而类与类之间还有另一种关系,这就是组合 先来看两个例子: 先定义两个类,一个老师类,老师类有名字,年龄,出生的 ...
- Python 面向对象编程之封装的艺术
1. 面向对象编程 OOP ( Object Oriented Programming) 即面向对象编程. 面向对象编程是一种编码思想,或是一种代码组织方式.如同编辑文章时,可以选择分段.分节的方式 ...
- python基础-面向对象编程之继承
面向对象编程之继承 继承的定义:是一种新建类的方式,新建的类称之为子类或派生类,被继承的父类称之为基类或超类 继承的作用:子类会""遗传"父类的属性,从而解决代码重用问题 ...
- python基础-面向对象编程之封装、访问限制机制和property
面向对象编程之封装 封装 定义:将属性和方法一股脑的封装到对象中,使对象可通过"对象."的方式获取或存储数据. 作用:让对象有了"."的机制,存取数据更加方便 ...
- python基础-面向对象编程之反射
面向对象编程之反射 反射 定义:通过字符串对对象的属性和方法进行操作. 反射有4个方法,都是python内置的,分别是: hasattr(obj,name:str) 通过"字符串" ...
- python基础-面向对象编程之多态
面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...
- python基础-面向对象编程之组合
面向对象编程之组合 定义:一个对象中拥有另一个或其他多个对象的属性和方法. 作用:减少代码的冗余,降低耦合度 关于耦合度的说明 耦合:通俗地讲,就是相互作用,相互影响的意思 耦合度越高,程序的可扩展性 ...
- Python编程之美:最佳实践指南PDF高清完整版免费下载|百度云盘|Python新手到进阶
百度云盘:Python编程之美:最佳实践指南PDF高清完整版免费下载 提取码:1py6 内容简介 <Python编程之美:最佳实践指南>是Python用户的一本百科式学习指南,由Pytho ...
- 深入理解JavaScript系列(17):面向对象编程之概论
介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基 ...
随机推荐
- C# 使用 MsieJavaScriptEngine 引擎运行JavaScript
用这个东西实现了一个js脚本引擎代码生成器,调研的时候这个东西的资料比较少. 我就根据自己的这点应用来讲解讲解,有错误,不符的地方还请园友指出. 使用 Nuget 安装 MsieJavaScriptE ...
- Oracle Mysql MSSql 三种数据库 随机查询 条 语句
1. Oracle,随机查询查询语句-20条 select * from ( select * from 表名 order by dbms_random.value ) where rownum ...
- How do I add a simple onClick event handler to a canvas element?
How do I add a simple onClick event handler to a canvas element? When you draw to a canvas element, ...
- 【后台管理系统】—— Ant Design Pro 页面相关(三)
一.卡片Card分类 与普通卡片使用区别:底部按钮及内容样式 <Card hoverable bodyStyle={{ paddingBottom: 20 }} actions={[ // 卡片 ...
- Git - 对一组仓库进行配置
对一组仓库使用一套配置,另一组仓库使用另一套配置的需求也是有的,比如公司仓库的配置和我个人项目的仓库配置并不完全相同,每次都修改单个仓库的配置太麻烦并且可能会粗心忘改了以错误的配置进行提交,如何对一个 ...
- EMQ插件通过HTTP连接认证服务器实现认证
需求 在EMQ中添加认证插件,将到来的MQTT连接的ClientID.UserName.Password通过HTTP协议发送到认证服务器,用返回的数据决定是否允许该连接: 在连接时和断开时向服务器发送 ...
- 测开之路一百四十四:ORM之SQLAlchemy查询
在上一篇的基础上,插入数据 查询 Department.query.all() # 用表对象查db.session.query(Department).all() # 用db对象查 查询前两条,直接p ...
- Flex String拼接
平时Flex String拼接的时候直接str+str2 今天就想看看Flex自带的函数好不好用,然后使用 str.concat(str2); Alert.show(str); 结果没有变化,才发现一 ...
- Scratch少儿编程系列:(一)版本的选择及安装
工欲善其事必先利其器,为了使用Scratch,首先要到官网上下载相关软件. 官网链接地址为:https://scratch.mit.edu/download,我用的是Windows系统,下载对应的安装 ...
- PHP5和PHP7引用对比(笔记)
php5在引入引用计数后,使用了refcount_gc来记录次数,同时使用is_ref_gc来记录是否是引用类型. 例如 $a = 'hello'; //$a->zval1(type=IS_ST ...