我们在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 面向对象编程之进阶使用的更多相关文章

  1. python面向对象编程之组合

    前面讲了面向类与对象的继承,知道了继承是一种什么"是"什么的关系. 然而类与类之间还有另一种关系,这就是组合 先来看两个例子: 先定义两个类,一个老师类,老师类有名字,年龄,出生的 ...

  2. Python 面向对象编程之封装的艺术

    1. 面向对象编程 OOP ( Object  Oriented Programming) 即面向对象编程. 面向对象编程是一种编码思想,或是一种代码组织方式.如同编辑文章时,可以选择分段.分节的方式 ...

  3. python基础-面向对象编程之继承

    面向对象编程之继承 继承的定义:是一种新建类的方式,新建的类称之为子类或派生类,被继承的父类称之为基类或超类 继承的作用:子类会""遗传"父类的属性,从而解决代码重用问题 ...

  4. python基础-面向对象编程之封装、访问限制机制和property

    面向对象编程之封装 封装 定义:将属性和方法一股脑的封装到对象中,使对象可通过"对象."的方式获取或存储数据. 作用:让对象有了"."的机制,存取数据更加方便 ...

  5. python基础-面向对象编程之反射

    面向对象编程之反射 反射 定义:通过字符串对对象的属性和方法进行操作. 反射有4个方法,都是python内置的,分别是: hasattr(obj,name:str) 通过"字符串" ...

  6. python基础-面向对象编程之多态

    面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...

  7. python基础-面向对象编程之组合

    面向对象编程之组合 定义:一个对象中拥有另一个或其他多个对象的属性和方法. 作用:减少代码的冗余,降低耦合度 关于耦合度的说明 耦合:通俗地讲,就是相互作用,相互影响的意思 耦合度越高,程序的可扩展性 ...

  8. Python编程之美:最佳实践指南PDF高清完整版免费下载|百度云盘|Python新手到进阶

    百度云盘:Python编程之美:最佳实践指南PDF高清完整版免费下载 提取码:1py6 内容简介 <Python编程之美:最佳实践指南>是Python用户的一本百科式学习指南,由Pytho ...

  9. 深入理解JavaScript系列(17):面向对象编程之概论

    介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基 ...

随机推荐

  1. 1、安装Scrapy

    一.网址:https://doc.scrapy.org/en/latest/intro/install.html 二.安装过程中出现"cl.exe"找不到的错误,解决方法:http ...

  2. 将数据库中带出的列,在gridview中影藏起来

    前台增加事件:OnRowCreated="GridView1_RowCreated" protected void GridView1_RowCreated(object send ...

  3. legend3---lavarel中使用qq邮箱发送邮件

    legend3---lavarel中使用qq邮箱发送邮件 一.总结 一句话总结: 第一步:配置邮箱做服务器,比如qq邮箱,网易163邮箱 第二步:配置lavarel的配置文件 第三部:写邮件发送代码就 ...

  4. __proto__ VS. prototype in JavaScript

    __proto__ VS. prototype in JavaScript http://dmitrysoshnikov.com/ecmascript/javascript-the-core/#a-p ...

  5. 一、基础篇--1.1Java基础-final, finally, finalize 的区别

    final, finally, finalize 首先,这三个关键字没什么关联,只是放在一起比较像,用法用处完全不同. final: final关键字可以用来修饰类.方法.变量(成员变量和局部变量), ...

  6. C 语言的函数 - 内存分析

    函数基本概念 Linux 中,函数在内存的代码段(code 区),地址比较靠前. 函数定义 C 语言中,函数有三个要素:入参.返回值.函数名,缺一不可.函数使用前必须先声明,或者在使用之前定义. 函数 ...

  7. python3 基本数据类型_1

    不得已,要学习python3了,之前了解到py2与py3有很大不同,不过学起来才能感觉到,比如print. 不过,同样的代码,可以使用py3,py2执行,结果也相似,大家可以看看. 大概因为初学,还未 ...

  8. Pytorch迁移学习

    环境: Pytorch1.1,Python3.6,win10/ubuntu18,GPU 正文 Pytorch构建ResNet18模型并训练,进行真实图片分类: 利用预训练的ResNet18模型进行Fi ...

  9. 精读《Optional chaining》

    1. 引言 备受开发者喜爱的特性 Optional chaining 在 2019.6.5 进入了 stage2,让我们详细读一下草案,了解一下这个特性的用法以及讨论要点. 借着这次精读草案,让我们了 ...

  10. Linux /dev/shm

    /dev/shm是Linux下的一个目录,/dev/shm目录不在磁盘上,而是在内存中,因此使用Linux /dev/shm的效率非常高,直接写进内存 可以通过两个脚本验证Linux /dev/shm ...