python之路day9_Python之路,Day7 - 面向对象编程进阶
本节内容面向对象高级语法部分静态方法、类方法、属性方法
类的特殊方法
反射
异常处理
Socket开发基础
作业开发一个支持多用户在线的FTP程序
面向对象高级语法部分
静态方法
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法什么是静态方法呢其实不难理解普通的方法可以在实例化后直接调用并且在方法里可以通过self.调用实例变量或类变量但静态方法是不可以访问实例变量或类变量的一个不能访问实例变量和类变量的方法其实相当于跟类本身已经没什么关系了它与类唯一的关联就是需要通过类名来调用这个方法class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod #把eat方法变为静态方法
def eat(self):
print("%s is eating" % self.name)
d = Dog("ChenRonghua")
d.eat()
上面的调用会出以下错误说是eat需要一个self参数但调用时却没有传递没错当eat变成静态方法后再通过实例调用时就不会自动把实例本身当作一个参数传给self了。Traceback (most recent call last):
File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/静态方法.py", line 17, in
d.eat()
TypeError: eat() missing 1 required positional argument: 'self'
想让上面的代码可以正常工作有两种办法
1. 调用时主动传递实例本身给eat方法即d.eat(d)
2. 在eat方法中去掉self参数但这也意味着在eat中不能通过self.调用实例中的其它变量了class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod
def eat():
print(" is eating")
d = Dog("ChenRonghua")
d.eat()
类方法
类方法通过@classmethod装饰器实现类方法和普通方法的区别是 类方法只能访问类变量不能访问实例变量class Dog(object):
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating" % self.name)
d = Dog("ChenRonghua")
d.eat()
执行报错如下说Dog没有name属性因为name是个实例变量类方法是不能访问实例变量的Traceback (most recent call last):
File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 16, in
d.eat()
File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 11, in eat
print("%s is eating" % self.name)
AttributeError: type object 'Dog' has no attribute 'name'
此时可以定义一个类变量也叫name,看下执行效果class Dog(object):
name = "我是类变量"
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("%s is eating" % self.name)
d = Dog("ChenRonghua")
d.eat()
#执行结果
我是类变量 is eating
属性方法
属性方法的作用就是通过@property把一个方法变成一个静态属性class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print(" %s is eating" %self.name)
d = Dog("ChenRonghua")
d.eat()
调用会出以下错误 说NoneType is not callable, 因为eat此时已经变成一个静态属性了 不是方法了 想调用已经不需要加()号了直接d.eat就可以了Traceback (most recent call last):
ChenRonghua is eating
File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 16, in
d.eat()
TypeError: 'NoneType' object is not callable
正常调用如下d = Dog("ChenRonghua")
d.eat
输出
ChenRonghua is eating
好吧把一个方法变成静态属性有什么卵用呢既然想要静态变量那直接定义成一个静态变量不就得了么well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的 比如 你想知道一个航班当前的状态是到达了、延迟了、取消了、还是已经飞走了 想知道这种状态你必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个status属性的值是一系列动作后才得到的结果所以你每次调用时其实它都要经过一系列的动作才返回你结果但这些动作过程不需要用户关心 用户只需要调用这个属性就可以明白 了么class Flight(object):
def __init__(self,name):
self.flight_name = name
def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1
@property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
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")
f = Flight("CA980")
f.flight_status
cool , 那现在我只能查询航班状态 既然这个flight_status已经是个属性了 那我能否给它赋值呢试试吧f = Flight("CA980")
f.flight_status
f.flight_status = 2
输出 说不能更改这个属性我擦。。。。怎么办怎么办。。。checking flight CA980 status
flight is arrived...
Traceback (most recent call last):
File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 58, in
f.flight_status = 2
AttributeError: can't set attribute
当然可以改 不过需要通过@proerty.setter装饰器再装饰一下此时 你需要写一个新方法 对这个flight_status进行更改。class Flight(object):
def __init__(self,name):
self.flight_name = name
def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1
@property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
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 : "canceled",
1 :"arrived",
2 : "departured"
}
print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )
@flight_status.deleter #删除
def flight_status(self):
print("status got removed...")
f = Flight("CA980")
f.flight_status
f.flight_status = 2 #触发@flight_status.setter
del f.flight_status #触发@flight_status.deleter
注意以上代码里还写了一个@flight_status.deleter, 是允许可以将这个属性删除
类的特殊成员方法
1. __doc__ 表示类的描述信息class Foo:
""" 描述类信息这是用于看片的神奇 """
def func(self):
pass
print Foo.__doc__
#输出类的描述信息
2. __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即输出类
析构方法当对象在内存中被释放时自动触发执行。注此方法一般无须定义因为Python是一门高级语言程序员在使用时无需关心内存的分配和释放因为此工作都是交给Python解释器来执行所以析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
5. __call__ 对象后面加括号触发执行。注构造方法的执行是由创建对象触发的即对象 = 类名() 而对于 __call__ 方法的执行是由对象后加括号触发的即对象() 或者 类()()lass Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print '__call__'
obj = Foo() # 执行 __init__
obj() # 执行 __call__
6. __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': , '__init__': , '__doc__': None}
obj1 = Province('HeBei',10000)
print obj1.__dict__
# 获取 对象obj1 的成员
# 输出{'count': 10000, 'name': 'HeBei'}
obj2 = Province('HeNan', 3888)
print obj2.__dict__
# 获取 对象obj1 的成员
# 输出{'count': 3888, 'name': 'HeNan'}
7.__str__如果一个类中定义了__str__方法那么在打印 对象 时默认输出该方法的返回值。class Foo:
def __str__(self):
return 'alex li'
obj = Foo()
print obj
# 输出alex li
8.__getitem__、__setitem__、__delitem__
用于索引操作如字典。以上分别表示获取、设置、删除数据class Foo(object):
def __getitem__(self, key):
print('__getitem__',key)
def __setitem__(self, key, value):
print('__setitem__',key,value)
def __delitem__(self, key):
print('__delitem__',key)
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
obj['k2'] = 'alex' # 自动触发执行 __setitem__
del obj['k1']
9. __new__ \ __metaclass__class Foo(object):
def __init__(self,name):
self.name = name
f = Foo("alex")
上述代码中obj 是通过 Foo 类实例化的对象其实不仅 obj 是一个对象Foo类本身也是一个对象因为在Python中一切事物都是对象。
如果按照一切事物都是对象的理论obj对象是通过执行Foo类的构造方法创建那么Foo类对象应该也是通过执行某个类的 构造方法 创建。print type(f) # 输出 表示obj 对象由Foo类创建
print type(Foo) # 输出 表示Foo类对象由 type 类创建
所以f对象是Foo类的一个实例Foo类对象是 type 类的一个实例即Foo类对象 是通过type类的构造方法创建。
那么创建类就可以有两种方式
a). 普通方式class Foo(object):
def func(self):
print 'hello alex'
b). 特殊方式def func(self):
print 'hello wupeiqi'
Foo = type('Foo',(object,), {'func': func})
#type第一个参数类名
#type第二个参数当前类的基类
#type第三个参数类的成员def func(self):
print("hello %s"%self.name)
def __init__(self,name,age):
self.name = name
self.age = age
Foo = type('Foo',(object,),{'func':func,'__init__':__init__})
f = Foo("jack",22)
f.func()
So 孩子记住类 是由 type 类实例化产生
那么问题来了类默认是由 type 类实例化产生type类中如何实现的创建类类又是如何创建对象
答类中有一个属性 __metaclass__其用来表示该类由 谁 来实例化创建所以我们可以为 __metaclass__ 设置一个type类的派生类从而查看 类 创建的过程。#_*_coding:utf-8_*_
__author__ = 'Alex Li'
class MyType(type):
def __init__(self, what, bases=None, dict=None):
print("--MyType init---")
super(MyType, self).__init__(what, bases, dict)
def __call__(self, *args, **kwargs):
print("--MyType call---")
obj = self.__new__(self, *args, **kwargs)
self.__init__(obj, *args, **kwargs)
class Foo(object):
__metaclass__ = MyType
def __init__(self, name):
self.name = name
print("Foo ---init__")
def __new__(cls, *args, **kwargs):
print("Foo --new--")
return object.__new__(cls)
# 第一阶段解释器从上到下执行代码创建Foo类
# 第二阶段通过Foo类创建obj对象
obj = Foo("Alex")
metaclass 详解文章http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好
反射
通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
hasattr(obj,name_str):判断 一个对象obj里是否有对应的字符串name_str的方法
getattr(obj,name_str) :根据字符串去获取obj里的方法
setattr(obj,’y’,v) : x.y=v 将x.y对应的值重新赋值,也可以增加一个并不属于类的类
delattr(obj,y) :将x.y对应的值删掉
getattr(object, name, default=None)def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass
hasattr(object,name)判断object中有没有一个name字符串对应的方法或属性
setattr(x,y,v)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''
delattr(x,y)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'' """
反射代码示例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', 18)
setattr(obj, 'show', lambda num: num + 1)
# #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')
动态导入模块import importlib
__import__('import_lib.metaclass') #这是解释器自己内部用的
#importlib.import_module('import_lib.metaclass') #与上面这句效果一样官方建议用这个
异常处理
参考 http://www.cnblogs.com/wupeiqi/articles/5017742.html
Socket 编程
参考http://www.cnblogs.com/wupeiqi/articles/5040823.html
python之路day9_Python之路,Day7 - 面向对象编程进阶相关推荐
- Day7 - 面向对象编程进阶及其他相关
参考文章:http://www.cnblogs.com/alex3714/articles/5213184.html 本节内容: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊成员方法 反 ...
- Python开发系列课程(11) - 面向对象编程进阶
面向对象编程进阶 在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息.为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象 ...
- Day7 - Python基础7 面向对象编程进阶 --转自金角大王
本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 经典 ...
- 《易学Python》——第6章 类与面向对象编程 6.1 类是什么
本节书摘来自异步社区<易学Python>一书中的第6章,第6.1节,作者[澳]Anthony Briggs,王威,袁国忠 译,更多章节内容可以访问云栖社区"异步社区"公 ...
- python的核心理念是什么_Python 面向对象编程的核心概念知识点简介
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 以下文章来源于 无量测试之道 ,作者: 无量测试之道 刚接触Python的新手.小白,可以复制下面 ...
- python oop求三角形面积公式_Python面向对象编程-OOP
Python面向对象编程-OOP 20141216 Chenxin整理 OOP的3大特性: 封装,继承,多态 一.封装 OOP目的,OOP为了代码重用 :分解代码 ,最小化代码的冗余以及对现在的代码进 ...
- python实现回合制对战游戏-面向对象编程
什么是面向对象编程: Object Oriented Programming,简称OOP,面向对象编程就是以类的方式组织代码,以对象的形式封装数据. # 面向过程的编程:着重于做什么 # 面向对象的编 ...
- python之路day9_python之路day9作业
2.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. def test(data): return data[1::2] li = [11,22,33,44 ...
- python面向对象语言_Python语言基础之——面向对象编程
1.类属性 1)类属性: 直接定义在类中的变量是类属性 类属性的值不会因为对象不同而不一样 2)对象属性 通过 self.属性名 = 值 定义在init函数中的属性 对象属性的值会因为对象不同而不一样 ...
- Python学习笔记——基础篇【第七周】———FTP作业(面向对象编程进阶 Socket编程基础)...
FTP作业 本节内容: 面向对象高级语法部分 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 参考:http://www.cnblogs.com/wupeiqi/ ...
最新文章
- 详解 CSS 属性 - 伪类和伪元素的区别
- python语言程序设计慕课_中国大学MOOC(慕课)_Python语言程序设计基础_试题及答案...
- Tomcat启动报Error listenerStart错误
- RecyclerView 数据预取
- SQL Server之 (四) ADO增删查改 登录demo 带参数的sql语句 插入自动返回行号
- vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
- 【路径规划】基于matlab自动化拣货最优路径【含Matlab源码 1713期】
- 自动格式化SQL工具推荐
- 测试抑郁症软件,App Store 上的“抑郁症测试 - 心理测试”
- XML与XSD两兄弟
- RHCE考试题及讲解(一)
- VS下同一个solution下不同project之间头文件的相互调用
- 北航计算机学院编译技术,北航编译技术在线作业一二三
- pcs增加mysql资源_pcs命令配置示例(详细版)
- windows编写linux脚本,适用于 Windows 和 Linux 的脚本编写工具包
- java初中级面试题集锦
- python小象学院: BMR------ 基础代谢率1.0
- 阿里云产品头条(2018年2月刊)
- EventBus: Subscriber class XXX and its super classes have no public method with the @Subscribe
- linux对电子信息工程专业的意义,谈谈我眼中的电子信息工程
热门文章
- 使用监听器生成请求记录日志
- JSTL表达式的理解和使用
- 08cms php5.6,大型房产门户08cms单城市商业版V8.4(带升级补丁),带手机独家放送,去除后门优化响应...
- 为什么使用@tablename起别名产生的sql语句不能用_宜信-运维-SQL优化|一文说清Oracle Hint的正确使用姿势...
- c语言 滑窗法_滑窗算法
- php怎么判断文件在下载,php文件下载显示找不到文件怎么办
- java list t 类_Java ListT 、List?、ListObject、ListE、ListU的区别
- string.format的使用与及转义
- PHP面试之网络协议面试题
- C#语言和SQL Server数据库技术_前四章错题