Python-Day7 面向对象进阶/异常处理/Socket
一、面向对象高级语法部分
1.静态方法
通过@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("ha")
- d.eat()
上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
- <span style="color: #ff0000;">Traceback (most recent call last):
- File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/静态方法.py", line 17, in <module>
- d.eat()
- TypeError: eat() missing 1 required positional argument: 'self'
- </span>
想让上面的代码可以正常工作有两种办法
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("ha")
- d.eat()
2.类方法
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。
- class Dog(object):
- def __init__(self,name):
- self.name = name
- @classmethod
- def eat(self):
- print("%s is eating" % self.name)
- d = Dog("ha")
- d.eat()
执行报错如下,说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的
- Traceback (most recent call last):
- File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 16, in <module>
- 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("ha")
- d.eat()
- #执行结果
- 我是类变量 is eating
3.属性方法
属性方法的作用就是通过@property把一个方法变成一个静态属性
- class Dog(object):
- def __init__(self,name):
- self.name = name
- @property
- def eat(self):
- print(" %s is eating" %self.name)
- d = Dog("ha")
- 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 <module>
- d.eat()
- TypeError: 'NoneType' object is not callable
正常调用如下
- d = Dog("ha")
- d.eat
- 输出
- ha is eating
4.类的特殊成员方法
__doc__ 表示类的描述信息
- class Foo:
- """ 描述类信息,这是用于看片的神奇 """
- def func(self):
- pass
- print Foo.__doc__
- #输出:类的描述信息
__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,即:输出类
__init__ 构造方法,通过类创建对象时,自动触发执行
__del__ 析构方法,当对象在内存中被释放时,自动触发执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
__call__ 对象后面加括号,触发执行
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
__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': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__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'}
__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
- class Foo:
- def __str__(self):
- return 'alex li'
- obj = Foo()
- print obj
- # 输出:alex li
__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']
__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) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
- print type(Foo) # 输出:<type 'type'> 表示,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()
类 是由 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")
五、反射
通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
① hasattr(obj,str) 判断一个对象obj里是否有对应的str字符串的方法
② getattr(obj,str) 根据字符串去获取obj对象里的对应的方法的内存地址
- #hasattr、getattr
- class Foo(object):
- def __init__(self,name):
- self.name = name
- def func(self):
- print("func",self.name)
- obj = Foo("alex")
- str = "func"
- print(hasattr(obj,str)) # 检查是否含有成员 有没有obj.str属性
- if hasattr(obj,str):
- getattr(obj,str)() #getattr(obj,str) = obj.str
- # True
- # func alex
③ setattr(obj,'y','z') obj.y = z
- #setattr
- def bulk(self):
- print("%s is yelling"%self.name)
- class Foo(object):
- def __init__(self,name):
- self.name = name
- def func(self):
- print("func",self.name)
- obj = Foo("alex")
- str = "talk"
- print(hasattr(obj,str)) # 检查是否含有成员 有没有obj.str属性
- if hasattr(obj,str):
- getattr(obj,str)() # getattr(obj,str) = obj.str
- else:
- setattr(obj,str,bulk) # setattr(obj,str,bulk 相当于 obj.str = bulk
- getattr(obj,str)(obj)
- # False
- # alex is yelling
④ delattr(obj,str) 删除obj.str
- #delattr
- class Foo(object):
- def __init__(self,name):
- self.name = name
- def func(self):
- print("func",self.name)
- obj = Foo("alex")
- str = "name"
- if hasattr(obj,str):
- delattr(obj,str) # 删除属性obj.str
- print(obj.name)
- # Traceback (most recent call last):
- # File "C:/Users/L/PycharmProjects/s14/preview/Day7/main.py", line 40, in <module>
- # print(obj.name)
- # AttributeError: 'Foo' object has no attribute 'name'
二、异常处理
1、异常基础
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!
- #异常处理
- list = ["hello","world"]
- try:
- list[3]
- except IndexError as e:
- print("IndexError",e)
- # IndexError list index out of range
上面程序表示try里面的代码如果出现IndexError这种错误,则执行except下面的代码,不会把错误信息显示给用户,程序也不会停止;目前只能处理IndexError这一种异常,想处理多种异常还可以这么写:
- #多种异常处理
- list = ["hello","world"]
- try:
- list[3]
- except IndexError as e:
- print("IndexError",e)
- except KeyError as e:
- print("KeyError", e)
- except ValueError as e:
- print("ValueError",e)
- # IndexError list index out of range
万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常
- #万能异常处理
- list = ["hello","world"]
- try:
- list[3]
- except Exception as e:
- print("Error",e)
- #Error list index out of range
- 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
全部异常
2、异常的其他结构
- #异常的其他结构
- try:
- # 主代码块
- pass
- except KeyError as e:
- # 异常时,执行该块
- pass
- else:
- # 主代码块执行完,执行该块
- pass
- finally:
- # 无论异常与否,最终执行该块
- pass
3、自定义异常
- #主动触发异常
- try:
- raise Exception('错误了。。。')
- except Exception as e:
- print(e)
- #错误了。。。
- #自定义异常
- class Diyexception(Exception):
- def __init__(self, msg):
- self.message = msg
- def __str__(self):
- return self.message
- error = Diyexception("报错了....")
- try:
- raise error
- except Diyexception as e:
- print(e)
- #报错了....
Python-Day7 面向对象进阶/异常处理/Socket的更多相关文章
- python基础——面向对象进阶下
python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...
- python基础——面向对象进阶
python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...
- Python 3 面向对象进阶
Python 3 面向对象进阶 一. isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的 ...
- Python面向对象进阶和socket网络编程-day08
写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...
- Python面向对象进阶和socket网络编程
写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...
- day021|python之面向对象进阶1
面向对象进阶 目录 面向对象进阶 1 继承 1.1 继承入门 1.1.1 继承基础 1.1.2 类的基本使用 1.2 多继承 1.2.1 多继承的基本使用 1.2.2 多继承以后的重复性 1.3 类的 ...
- python学习笔记-(十一)面向对象进阶&异常处理
上篇我们已经了解了一些面向对象的基础知识,本次就了解下面向对象的一些进阶知识(虽然我也不知道有什么卵用). 静态方法 静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作.使 ...
- 第七天 面向对象进阶与socket编程
1.静态方法(用得少)(解除某个函数跟类的关联,加了静态方法后,类便不能将类的参数传给静态方法函数了) class Dog(object): def __init__(self,name): @sta ...
- day7 面向对象进阶
面向对象高级语法部分 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例 ...
随机推荐
- TCP/IP协议原理与应用笔记27:网际协议(IP)之 选项(Options)
1. 选项(Options) (1)作用:网络测试或者调试,可选 (2)格式:0~40 bytes 2. 选项类型:
- 【阿里云产品公测】阿里云ACE部署通用完整教程及评测
[阿里云产品公测]阿里云ACE部署通用完整教程及评测 作者:阿里云用户bailimei ACE应该是目前在公测的服务中应用最广泛的一项服务.在公测云引擎ACE前曾使用过新浪SAE,而ACE给我的最初印 ...
- 【Linux/Ubuntu学习 7】E: 无法获得锁 /var/lib/dpkg/lock – open (11: 资源暂时不可用) E: 无法锁定管理目录
在用sudo apt-get install 安装软件时,由于速度太慢,想换个软件源,直接关闭了终端,apt-get但进程没有结束,结果终端提示 :“E: 无法获得锁 /var/lib/dpkg/lo ...
- Oracle基础<1>--数据库设计
一:为什么需要使用数据库设计 数据库设计可以使数据库通过健壮的数据库结构 高效并且健康 的进行工作. 二.数据库设计原则 (数据库设计.系统设计.架构设计) 1.熟悉需求 保证之后需求的变更 不会 ...
- java 远程调试
在java 命令上加入 -Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y suspend=y 配置的端口时候要保证没有被占用
- 剑指Offer23 二叉树中和为sum的路径
/************************************************************************* > File Name: 23_FindPa ...
- CPU 硬盘性能到底相差多少
本文以一个现代的.实际的个人电脑为对象,分析其中CPU(Intel Core 2 Duo 3.0GHz)以及各类子系统的运行速度——延迟和数据吞吐量.通过粗略的估算PC各个组件的相对运行速度,希望能给 ...
- dropdownlist值改变时调用js
DropDownList的OnSelectedIndexChanged方法是服务器端方法如要用需要设置AutoPostBack选项为true,并且在服务器后台写方法 要调用js方法需要onchange ...
- JVM内存分配
内存分配:当JVM运行起来的时候就会给内存划分空间,那么这块空间称之为运行时数据区.(备注:当一个Java源程序编译成class字节码文件之后,字节码文件里存放的都是二进制的汇编命令,当程序运行的时候 ...
- 应用型GIS 地理信息系统设计内容和方法
挺好的一篇论 文 http://wenku.baidu.com/view/8e40a17c1711cc7931b7165e.html 文章就重点应用型地理信息系统的设计内容.设计过程.相关实现技术与方 ...