一、面向对象高级语法部分

1.静态方法

    通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @staticmethod #把eat方法变为静态方法
  7. def eat(self):
  8. print("%s is eating" % self.name)
  9.  
  10. d = Dog("ha")
  11. d.eat()

上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。

  1. <span style="color: #ff0000;">Traceback (most recent call last):
  2. File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/静态方法.py", line 17, in <module>
  3. d.eat()
  4. TypeError: eat() missing 1 required positional argument: 'self'
  5. </span>

想让上面的代码可以正常工作有两种办法

1. 调用时主动传递实例本身给eat方法,即d.eat(d)

2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @staticmethod
  7. def eat():
  8. print(" is eating")
  9.  
  10. d = Dog("ha")
  11. d.eat()

2.类方法

类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。

  1. class Dog(object):
  2. def __init__(self,name):
  3. self.name = name
  4.  
  5. @classmethod
  6. def eat(self):
  7. print("%s is eating" % self.name)
  8.  
  9. d = Dog("ha")
  10. d.eat()

执行报错如下,说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的

  1. Traceback (most recent call last):
  2. File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 16, in <module>
  3. d.eat()
  4. File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 11, in eat
  5. print("%s is eating" % self.name)
  6. AttributeError: type object 'Dog' has no attribute 'name'

此时可以定义一个类变量,也叫name,看下执行效果

  1. class Dog(object):
  2. name = "我是类变量"
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @classmethod
  7. def eat(self):
  8. print("%s is eating" % self.name)
  9.  
  10. d = Dog("ha")
  11. d.eat()
  12.  
  13. #执行结果
  14.  
  15. 我是类变量 is eating

3.属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @property
  7. def eat(self):
  8. print(" %s is eating" %self.name)
  9.  
  10. d = Dog("ha")
  11. d.eat()

调用会出以下错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了

  1. Traceback (most recent call last):
  2. ChenRonghua is eating
  3. File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 16, in <module>
  4. d.eat()
  5. TypeError: 'NoneType' object is not callable

正常调用如下

  1. d = Dog("ha")
  2. d.eat
  3.  
  4. 输出
  5. ha is eating

4.类的特殊成员方法

__doc__  表示类的描述信息

  1. class Foo:
  2. """ 描述类信息,这是用于看片的神奇 """
  3.  
  4. def func(self):
  5. pass
  6.  
  7. print Foo.__doc__
  8. #输出:类的描述信息

__module__ 和  __class__

__module__ 表示当前操作的对象在那个模块

__class__     表示当前操作的对象的类是什么

  1. class C:
  2.  
  3. def __init__(self):
  4. self.name = 'wupeiqi'
  1. from lib.aa import C
  2.  
  3. obj = C()
  4. print obj.__module__ # 输出 lib.aa,即:输出模块
  5. print obj.__class__ # 输出 lib.aa.C,即:输出类

__init__ 构造方法,通过类创建对象时,自动触发执行

__del__ 析构方法,当对象在内存中被释放时,自动触发执行

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

__call__ 对象后面加括号,触发执行


  
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

__dict__ 查看类或对象中的所有成员

  1. class Province:
  2.  
  3. country = 'China'
  4.  
  5. def __init__(self, name, count):
  6. self.name = name
  7. self.count = count
  8.  
  9. def func(self, *args, **kwargs):
  10. print 'func'
  11.  
  12. # 获取类的成员,即:静态字段、方法、
  13. print Province.__dict__
  14. # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
  15.  
  16. obj1 = Province('HeBei',10000)
  17. print obj1.__dict__
  18. # 获取 对象obj1 的成员
  19. # 输出:{'count': 10000, 'name': 'HeBei'}
  20.  
  21. obj2 = Province('HeNan', 3888)
  22. print obj2.__dict__
  23. # 获取 对象obj1 的成员
  24. # 输出:{'count': 3888, 'name': 'HeNan'}

__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

  1. class Foo:
  2.  
  3. def __str__(self):
  4. return 'alex li'
  5.  
  6. obj = Foo()
  7. print obj
  8. # 输出:alex li

__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

  1. class Foo(object):
  2.  
  3. def __getitem__(self, key):
  4. print('__getitem__',key)
  5.  
  6. def __setitem__(self, key, value):
  7. print('__setitem__',key,value)
  8.  
  9. def __delitem__(self, key):
  10. print('__delitem__',key)
  11.  
  12. obj = Foo()
  13.  
  14. result = obj['k1'] # 自动触发执行 __getitem__
  15. obj['k2'] = 'alex' # 自动触发执行 __setitem__
  16. del obj['k1']

__new__ \ __metaclass__

  1. class Foo(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. f = Foo("alex")

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

  1. print type(f) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
  2. print type(Foo) # 输出:<type 'type'> 表示,Foo类对象由 type 类创建

所以,f对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

a). 普通方式

  1. class Foo(object):
  2.  
  3. def func(self):
  4. print 'hello alex'

b). 特殊方式

  1. def func(self):
  2. print 'hello wupeiqi'
  3.  
  4. Foo = type('Foo',(object,), {'func': func})
  5. #type第一个参数:类名
  6. #type第二个参数:当前类的基类
  7. #type第三个参数:类的成员
  1. def func(self):
  2. print("hello %s"%self.name)
  3.  
  4. def __init__(self,name,age):
  5. self.name = name
  6. self.age = age
  7. Foo = type('Foo',(object,),{'func':func,'__init__':__init__})
  8.  
  9. f = Foo("jack",22)
  10. f.func()

类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

  1. #_*_coding:utf-8_*_
  2. __author__ = 'Alex Li'
  3.  
  4. class MyType(type):
  5.  
  6. def __init__(self, what, bases=None, dict=None):
  7. print("--MyType init---")
  8. super(MyType, self).__init__(what, bases, dict)
  9.  
  10. def __call__(self, *args, **kwargs):
  11. print("--MyType call---")
  12. obj = self.__new__(self, *args, **kwargs)
  13.  
  14. self.__init__(obj, *args, **kwargs)
  15.  
  16. class Foo(object):
  17.  
  18. __metaclass__ = MyType
  19.  
  20. def __init__(self, name):
  21. self.name = name
  22. print("Foo ---init__")
  23.  
  24. def __new__(cls, *args, **kwargs):
  25. print("Foo --new--")
  26. return object.__new__(cls)
  27.  
  28. # 第一阶段:解释器从上到下执行代码创建Foo类
  29. # 第二阶段:通过Foo类创建obj对象
  30. obj = Foo("Alex")

五、反射

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

① hasattr(obj,str) 判断一个对象obj里是否有对应的str字符串的方法

② getattr(obj,str) 根据字符串去获取obj对象里的对应的方法的内存地址

  1. #hasattr、getattr
  2.  
  3. class Foo(object):
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. def func(self):
  8. print("func",self.name)
  9.  
  10. obj = Foo("alex")
  11. str = "func"
  12.  
  13. print(hasattr(obj,str)) # 检查是否含有成员 有没有obj.str属性
  14.  
  15. if hasattr(obj,str):
  16. getattr(obj,str)() #getattr(obj,str) = obj.str
  17.  
  18. # True
  19. # func alex

③ setattr(obj,'y','z')  obj.y = z

  1. #setattr
  2.  
  3. def bulk(self):
  4. print("%s is yelling"%self.name)
  5.  
  6. class Foo(object):
  7. def __init__(self,name):
  8. self.name = name
  9.  
  10. def func(self):
  11. print("func",self.name)
  12.  
  13. obj = Foo("alex")
  14. str = "talk"
  15.  
  16. print(hasattr(obj,str)) # 检查是否含有成员 有没有obj.str属性
  17.  
  18. if hasattr(obj,str):
  19. getattr(obj,str)() # getattr(obj,str) = obj.str
  20.  
  21. else:
  22. setattr(obj,str,bulk) # setattr(obj,str,bulk 相当于 obj.str = bulk
  23. getattr(obj,str)(obj)
  24.  
  25. # False
  26. # alex is yelling

④ delattr(obj,str) 删除obj.str

  1. #delattr
  2.  
  3. class Foo(object):
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. def func(self):
  8. print("func",self.name)
  9.  
  10. obj = Foo("alex")
  11. str = "name"
  12.  
  13. if hasattr(obj,str):
  14. delattr(obj,str) # 删除属性obj.str
  15.  
  16. print(obj.name)
  17.  
  18. # Traceback (most recent call last):
  19. # File "C:/Users/L/PycharmProjects/s14/preview/Day7/main.py", line 40, in <module>
  20. # print(obj.name)
  21. # AttributeError: 'Foo' object has no attribute 'name'

二、异常处理

1、异常基础

在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

  1. #异常处理
  2.  
  3. list = ["hello","world"]
  4. try:
  5. list[3]
  6. except IndexError as e:
  7. print("IndexError",e)
  8.  
  9. # IndexError list index out of range

上面程序表示try里面的代码如果出现IndexError这种错误,则执行except下面的代码,不会把错误信息显示给用户,程序也不会停止;目前只能处理IndexError这一种异常,想处理多种异常还可以这么写:

  1. #多种异常处理
  2.  
  3. list = ["hello","world"]
  4. try:
  5. list[3]
  6. except IndexError as e:
  7. print("IndexError",e)
  8.  
  9. except KeyError as e:
  10. print("KeyError", e)
  11.  
  12. except ValueError as e:
  13. print("ValueError",e)
  14.  
  15. # IndexError list index out of range

万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常

  1. #万能异常处理
  2.  
  3. list = ["hello","world"]
  4. try:
  5. list[3]
  6. except Exception as e:
  7. print("Error",e)
  8.  
  9. #Error list index out of range
  1. AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
  2. IOError 输入/输出异常;基本上是无法打开文件
  3. ImportError 无法引入模块或包;基本上是路径问题或名称错误
  4. IndentationError 语法错误(的子类) ;代码没有正确对齐
  5. IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
  6. KeyError 试图访问字典里不存在的键
  7. KeyboardInterrupt Ctrl+C被按下
  8. NameError 使用一个还未被赋予对象的变量
  9. SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
  10. TypeError 传入对象类型与要求的不符合
  11. UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
  12. 导致你以为正在访问它
  13. ValueError 传入一个调用者不期望的值,即使值的类型是正确的
  1. ArithmeticError
  2. AssertionError
  3. AttributeError
  4. BaseException
  5. BufferError
  6. BytesWarning
  7. DeprecationWarning
  8. EnvironmentError
  9. EOFError
  10. Exception
  11. FloatingPointError
  12. FutureWarning
  13. GeneratorExit
  14. ImportError
  15. ImportWarning
  16. IndentationError
  17. IndexError
  18. IOError
  19. KeyboardInterrupt
  20. KeyError
  21. LookupError
  22. MemoryError
  23. NameError
  24. NotImplementedError
  25. OSError
  26. OverflowError
  27. PendingDeprecationWarning
  28. ReferenceError
  29. RuntimeError
  30. RuntimeWarning
  31. StandardError
  32. StopIteration
  33. SyntaxError
  34. SyntaxWarning
  35. SystemError
  36. SystemExit
  37. TabError
  38. TypeError
  39. UnboundLocalError
  40. UnicodeDecodeError
  41. UnicodeEncodeError
  42. UnicodeError
  43. UnicodeTranslateError
  44. UnicodeWarning
  45. UserWarning
  46. ValueError
  47. Warning
  48. ZeroDivisionError

全部异常

2、异常的其他结构

  1. #异常的其他结构
  2.  
  3. try:
  4. # 主代码块
  5. pass
  6. except KeyError as e:
  7. # 异常时,执行该块
  8. pass
  9. else:
  10. # 主代码块执行完,执行该块
  11. pass
  12. finally:
  13. # 无论异常与否,最终执行该块
  14. pass

3、自定义异常 

  1. #主动触发异常
  2.  
  3. try:
  4. raise Exception('错误了。。。')
  5. except Exception as e:
  6. print(e)
  7.  
  8. #错误了。。。
  1. #自定义异常
  2.  
  3. class Diyexception(Exception):
  4. def __init__(self, msg):
  5. self.message = msg
  6.  
  7. def __str__(self):
  8. return self.message
  9.  
  10. error = Diyexception("报错了....")
  11.  
  12. try:
  13. raise error
  14.  
  15. except Diyexception as e:
  16. print(e)
  17.  
  18. #报错了....

Python-Day7 面向对象进阶/异常处理/Socket的更多相关文章

  1. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  2. python基础——面向对象进阶

    python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...

  3. Python 3 面向对象进阶

    Python 3 面向对象进阶 一.    isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的 ...

  4. Python面向对象进阶和socket网络编程-day08

    写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...

  5. Python面向对象进阶和socket网络编程

    写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...

  6. day021|python之面向对象进阶1

    面向对象进阶 目录 面向对象进阶 1 继承 1.1 继承入门 1.1.1 继承基础 1.1.2 类的基本使用 1.2 多继承 1.2.1 多继承的基本使用 1.2.2 多继承以后的重复性 1.3 类的 ...

  7. python学习笔记-(十一)面向对象进阶&异常处理

    上篇我们已经了解了一些面向对象的基础知识,本次就了解下面向对象的一些进阶知识(虽然我也不知道有什么卵用). 静态方法 静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作.使 ...

  8. 第七天 面向对象进阶与socket编程

    1.静态方法(用得少)(解除某个函数跟类的关联,加了静态方法后,类便不能将类的参数传给静态方法函数了) class Dog(object): def __init__(self,name): @sta ...

  9. day7 面向对象进阶

    面向对象高级语法部分 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例 ...

随机推荐

  1. TCP/IP协议原理与应用笔记27:网际协议(IP)之 选项(Options)

    1. 选项(Options) (1)作用:网络测试或者调试,可选 (2)格式:0~40 bytes 2. 选项类型:

  2. 【阿里云产品公测】阿里云ACE部署通用完整教程及评测

    [阿里云产品公测]阿里云ACE部署通用完整教程及评测 作者:阿里云用户bailimei ACE应该是目前在公测的服务中应用最广泛的一项服务.在公测云引擎ACE前曾使用过新浪SAE,而ACE给我的最初印 ...

  3. 【Linux/Ubuntu学习 7】E: 无法获得锁 /var/lib/dpkg/lock – open (11: 资源暂时不可用) E: 无法锁定管理目录

    在用sudo apt-get install 安装软件时,由于速度太慢,想换个软件源,直接关闭了终端,apt-get但进程没有结束,结果终端提示 :“E: 无法获得锁 /var/lib/dpkg/lo ...

  4. Oracle基础<1>--数据库设计

    一:为什么需要使用数据库设计 数据库设计可以使数据库通过健壮的数据库结构  高效并且健康  的进行工作. 二.数据库设计原则 (数据库设计.系统设计.架构设计) 1.熟悉需求 保证之后需求的变更 不会 ...

  5. java 远程调试

    在java 命令上加入 -Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y suspend=y 配置的端口时候要保证没有被占用

  6. 剑指Offer23 二叉树中和为sum的路径

    /************************************************************************* > File Name: 23_FindPa ...

  7. CPU 硬盘性能到底相差多少

    本文以一个现代的.实际的个人电脑为对象,分析其中CPU(Intel Core 2 Duo 3.0GHz)以及各类子系统的运行速度——延迟和数据吞吐量.通过粗略的估算PC各个组件的相对运行速度,希望能给 ...

  8. dropdownlist值改变时调用js

    DropDownList的OnSelectedIndexChanged方法是服务器端方法如要用需要设置AutoPostBack选项为true,并且在服务器后台写方法 要调用js方法需要onchange ...

  9. JVM内存分配

    内存分配:当JVM运行起来的时候就会给内存划分空间,那么这块空间称之为运行时数据区.(备注:当一个Java源程序编译成class字节码文件之后,字节码文件里存放的都是二进制的汇编命令,当程序运行的时候 ...

  10. 应用型GIS 地理信息系统设计内容和方法

    挺好的一篇论 文 http://wenku.baidu.com/view/8e40a17c1711cc7931b7165e.html 文章就重点应用型地理信息系统的设计内容.设计过程.相关实现技术与方 ...