Python全栈开发-Day7-面向对象编程2

本节内容:

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

    1)静态方法、类方法、属性方法

    3)类的特殊方法  

    4)反射

  2、异常处理

静态方法

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


1

2

3

4

5

6

7

8

9

10

11

12

13

class Dog(object):

    def __init__(self,name):

        self.name = name

    @staticmethod #把eat方法变为静态方法

    def eat(self):

        print("%s is eating" % self.name)

= Dog("ZhangSan")

d.eat()

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

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

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
11
12 d = Dog("ZhangSan")
13 d.eat() 

类方法  

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


1

2

3

4

5

6

7

8

9

10

11

12

class Dog(object):

    def __init__(self,name):

        self.name = name

    @classmethod

    def eat(self):

        print("%s is eating" % self.name)

= Dog("ZhangSan")

d.eat()

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


1

2

3

4

5

6

Traceback (most recent call last):

  File "/Users/Gavin/PycharmProjects/python/类方法.py", line 16in <module>

    d.eat()

  File "/Users/jieli/PycharmProjects/python/类方法.py", line 11in eat

    print("%s is eating" % self.name)

AttributeError: type object ‘Dog‘ has no attribute ‘name‘

此时可以定义一个类变量,也叫name,并执行:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Dog(object):

    name = "我是类变量"

    def __init__(self,name):

        self.name = name

    @classmethod

    def eat(self):

        print("%s is eating" % self.name)

= Dog("ZhangSan")

d.eat()

#执行结果

我是类变量 is eating

属性方法  

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


1

2

3

4

5

6

7

8

9

10

11

12

class Dog(object):

    def __init__(self,name):

        self.name = name

    @property

    def eat(self):

        print(" %s is eating" %self.name)

= Dog("ZhangSan")

d.eat()

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


1

2

3

4

5

Traceback (most recent call last):

 ChenRonghua is eating

  File "/Users/Gavin/PycharmProjects/python/属性方法.py", line 16in <module>

    d.eat()

TypeError: ‘NoneType‘ object is not callable

正常调用如下


1

2

3

4

5

= Dog("ZhangSan")

d.eat

输出

 ZhangSan is eating

类的特殊方法

1. __doc__  表示类的描述信息


1

2

3

4

5

6

7

8

class Foo:

    """ 描述类信息 """

    def func(self):

        pass

printFoo.__doc__)

#输出:描述类信息

2. __module__ 和  __class__ 

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

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

新建一个文件lib.aa.py,内容如下class C:

    def __init__(self):
        self.name = ‘Simons‘

在另一个文件下运行:
from lib.aa import C

obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

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

4.__del__

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

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

5. __call__ 方法,在实例化的对象后面加括号,触发执行。

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


1

2

3

4

5

6

7

8

9

10

11

12

class Foo:

    def __init__(self):

        pass

    

    def __call__(self*args, **kwargs):

        print ‘__call__‘

obj = Foo() # 执行 __init__

obj()       # 执行 __call__

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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__

# 打印所有实例属性,【注意】:但不包括类属性

# 输出:{‘count‘: 10000, ‘name‘: ‘HeBei‘}

obj2 = Province(‘HeNan‘3888)

print obj2.__dict__

# 获取 对象obj1 的成员,不包括类属性

# 输出:{‘count‘: 3888, ‘name‘: ‘HeNan‘}

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


1

2

3

4

5

6

7

8

9

class Foo:

    def __str__(self):

        return ‘Gavin Simons‘

obj = Foo()

print obj

# 输出:Gavin Simons

8.__getitem__、__setitem__、__delitem__

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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‘= ‘gavin‘        # 自动触发执行 __setitem__

del obj[‘k1‘]      # 自动触发执行 __delitem__

反射

反射的作用就是,把字符串反射成内存中的对象或地址,进行来回的调用。这个功能很重要,因为这里实现了动态的内存装配。

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

getattr(object, name, default=None)  #如果name是方法名,则返回方法的内存地址,如果是属性则返回具体数值

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‘)

异常处理

参考 http://www.cnblogs.com/wupeiqi/articles/5017742.html

PS:最近在搬家,一直没有时间更新,搬到新家没有wifi,环境十分艰苦,o(╥﹏╥)o。就算使用4G流量,也争取加快更新速度。

时间: 2024-10-11 09:53:26

Python全栈开发-Day7-面向对象编程2的相关文章

Python全栈开发之面向对象

No.1 概念 面向对象的特点? 注重对象和指责,不同的对象承担各自的指责 更加适合对复杂的需求变化,专门应对复杂项目开发,提供固定的套路 面向对象强调的是谁来做,面向过程强调的如何做 什么是类 类是对一群具有相同特征或者行为的事物统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就是一个模板 什么是对象 对象是由类创建出来的一个具体存在,可以直接使用,通过哪个类创建出来的实例,就拥有哪个类中定义的特征和行为 类和对象的关系 类是模板,对象是根据类这个模板创建出来的,先有类,再有对

python全栈开发 * 23 面向对象 知识点汇总 * 180704

23 面向对象 -----特殊方法 1. isinstance(obj,类名) 判断对象是否是此类实例化或者此类的子类实例化出来的class A:passclass B(A):passb1=B()print(isinstance(b1,B)) # Trueprint(isinstance(b1,A)) # True2.issubclass(类名,类名1) 判断类名是否是类名1的子类class A:passclass B(A):passprint(issubclass(B,A)) #Truepri

Python全栈开发day7

一.Python生成器/迭代器 1 2 3 4 5 6 7 8 9 10 11 12 #!/bin/env python # -*- coding:utf-8 -*- def shaw(n):     start = 0     while True:         if start > n:             return         yield start # yield生成数据         start += 1 for i in shaw(10):  # for循环就为一个

python全栈开发 * 18 面向对象知识点汇总 * 180530

18 面向对象初识1class person: level="高级动物" mind="有思想" def __init__(self,name,age,gent,area,hobby): self.name=name self.age=age self.gent=gent self.area=area self.hobby=hobby print("__init__") pass def walk(self): pass def eat(self)

Python全栈开发之网络编程

No.1 TCP/IP 早期的计算机网络,都是由厂商规定自己的通信协议,互不兼容,为了把全世界不同类型的计算机连接起来,就必须规定一套全球通用的协议,所以就出现了TCP/IP No.2 Socket简介 要解决怎么标识一个进制,在一台电脑上可以同pid标识进程,但是在网络上是做不到的,其实TCP/IP就帮我们解决了这个问题,网络层的IP可以标识在网络上的主机,而传输层的协议+端口就可以标识主机中 什么是Socket socket是进程通信的的一种方式,它与其他进程通信的不同是,它能实现不同主机之

Python全栈开发之并发编程

No.1 线程 什么是多任务 就是操作系统可以同时运行多个任务,就是可以一边用浏览器上网,同时又可以听歌,还能再撩个×××姐,这就是多任务,操作系统会轮流把系统调度到每个核心上去执行 并发和并行 并发是指任务数多余cpu核数,通过操作系统的各种任务调度算法,实现多个任务 并行是指任务数小于cpu核数,即任务同时执行 单线程 import time def say_hello(i): print('hello ', i) if __name__ == '__main__': for i in ra

Python全栈开发-Day8-Socket网络编程

本节内容 断言 Socket构建框架 ftp构建框架 Socket粘包 Socket介绍 Socket参数介绍 基本Socket实例 通过Socket实现简单SSH SocketServer 支持多用户在线传输的FTP程序 1.断言 断言作用是,下面代码的执行要严格依据上面的执行结果,断言则为判断上面代码的结果是否符合下面代码执行的前提,有点类似于登机安检. assert type(obj.name) is str 上面这句话就是断言,如果断言为真,则继续执行下面代码,如果为假,则报错,错误类别

Python 全栈开发【第一篇】:目录

Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基础语法入门 Python 全栈开发[第三篇]:数据类型.字符编码.文件操作 第二阶段:函数编程&常用标准库 Python 全栈开发[第四篇]:函数.递归.生成器.迭代器 Pyhton 全栈开发[第五篇]:常用模块学习 第三阶段:面向对象编程&网络编程基础 Python 全栈开发[第六篇]:面向对象

python全栈开发学习目录

python全栈开发学习目录 第一章 计算机基础 第二章Python入门 第三章数据类型 第四章文件操作 第五章函数 第六章 模块 第七章 面向对象 第八章 网络编程 第九章 并发编程 第十章 数据库 第十一章 前端开发-html 第十一章 前端开发-css 附加:js特效 15个小demo 第十一章 前端开发-JavaScript 第十一章 前端开发-jQuery 第十一章 前端开发-bootstrap 第十二章 Django框架开发 ... 原文地址:https://www.cnblogs.

Python全栈【Socket网络编程】

Python全栈[socket网络编程] 本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字" 用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式