面向对象编程理解-2

时间:2021-04-30 17:22:29

11 析构方法:对象销毁的方法

   class类名:

          __del__(self):

                 pass

   析构方法会在对象销毁时被自动调用

python语言不建议在对象销毁时做任何事情,因此此方法的调用时间难以确定

12 预置实例属性:

12.1 __dict__属性:

   每个对象(实例)都有一个__dict__属性

   __dict__属性绑定一个存储此实例自身属性的字典

12.2 __doc__属性:

   用于保存的文档字符串,用于help()中的显示

   实例文档字符串和类的文档字符串相同

12.3 __class__属性

__class__属性绑定创建对象(实例)的类对象(类实例)

作用:

Ø  可以借助于此属性创建同类的实例

>>>car1 = car.a4.__class__

>>>car1

<class'car.Car'>

Ø  可以借助于此属性来访问类变量

12.4 __module__属性

   绑定此实例所属的模块

   在主模块中,此值为‘__mian__’

   不在主模块中,此值为模块名

13 类变量

13.1 定义

Ø  是指在class内定义的变量,此变量属于类,不属于此类的对象(实例)

Ø  类变量可以通过该类直接使用

Ø  类变量可以通过类的实例直接访问

Ø  类变量可以通过此类的对象的__class__属性直接访问

13.2 示例

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


14 类属性

14.1 __slots__ 属性
14.1.1 作用:

Ø  限定一个类创建的实例只能有固定的实例属性,不允许对象添加列表以外的实例属性

Ø  防止用户因错写属性名称而发生程序错误

14..1.2说明:

__slots__属性是一个列表,列表的值是字符串,含有__slots__属性的类所创建实例对象没有__dict__属性,即此实例不用字典来存储属性

class Student:

    __slots__ = ['name', 'age', 'score']

 

可以这样注释形参

 
    def __init__(self, n, a, s:’分数’):

        self.name = n

        self.age = a

        self.score = s

 

 

s = Student('曹焱兵', '20', '99')

print(s.score)

s.score = 100

print(s.score)

s.Score = 101

print(s.Score)

报错的原因是上面类属性__slot__已经限制了属性的个数,用这个属性后访问速度就会比较快,有些程序员为了优化代码

 
执行结果

99

100

Traceback (most recent call last):

  File "stu.py", line 14, in <module>

    s.Score = 101

AttributeError: 'Student' object has no attribute 'Score'

14.2 __class__属性

>>> import math

>>> math.__class__

<class 'module'>

>>> 

14.3 __doc__属性

文档字符串

 

15 对象的属性管理

15.1函数getattr(obj,name[,default])

从一个对象得到对象的属性,getattr(x,’y’)等同于x.y;

当属性不存在时,如果给出default参数,则返回default,如果没有给出default则产生一个AttributeError错误

15.2函数hasattr(obj,name)

用给定的name返回对象obj是否有此属性,此做法可以避免getattr()函数引发错误

15.3函数setattr(obj,name,value)

给对象obj的名为name的属性设置相应的值,set(x,’y’,v) 等同于x.y = v

15.4 函数detarrt(obj,name)

删除对象obj的name属性,delete(x,’y’)等同于del x.y

class myclass:

    pass

 

obj = myclass()

obj.a1 = 100

getattr(obj,'a1')  #字典存储是以字符串记录键的,也就是对象的属性

 

setattr(obj,'a2',200)

 

hasattr(obj,'a3')

 

delattr(obj,'a1')

16 用于类的函数:

16.1 isinstance(obj,类或类的元组) 

返回这个对象obj是否为某个类或某些类的对象,如果是返回True,否则返回False

16.2  trye(obj)

 返回对象的类型,可以根据此类型得到类实例

 

 

16.3 示例

class A:

    pass

    a = A()

 

    def fn(x):

        # 怎么判断x参数绑定的类型

        pass

       # 此函数可能根据不同的x类型,做不同的逻辑处理

        if isinstance(x, A):

            print("x是A类型的对象")

        elif isinstance(x, int):

            print("x是整型")

        elif isinstance(x, (A, tuple, list, str)):

            print("终于等到你")

    fn(1)

    fn(a)

    fn([1, 2, 3])

    if type(a) == A:

        print('a的类型是A')

    b = type(a)()  # 创建一个a类型的类实例

17 类方法 @classmethod

17.1 定义

类方法是只能访问类变量的方法

类方法需要使用@classmethod装饰器定义

类方法的第一个参数是类的实例,约定写为cls

17.2 说明:

   类实例和对象实例都可以调用类方法

   类方法不能访问实例变量

17.3示例

class ICBC:

    money = 10000000

 

    @classmethod

    def total_money(cls):   #类方法,类直接访问

        print('工商银行太原分行资产:', cls.money)

 

    def __init__(self,b):

        self.branch = b

        self.money = 5000000000000

        self.__class__.money -= 5000000

 

    def address(self):  #实例方法,必须有实例来调用

        print('地址',self.branch)

 

ICBC.total_money()    #1千万

b1 = ICBC('广渠门支行')

b1.total_money()       #5百万

print(b1.money)

 

 

18 类方法和实例方法对比

01)  类方法能够访问类变量,不能访问实例变量

实例方法能够访问类变量,也能访问实例变量

02)  类方法可以用实例来调用,也可以用类来调用

实例方法在调用时必须传入实例

19 静态方法 @staticmethod

19.1 定义

   静态方法是普通的函数

   静态方法定义在类的内部,只能凭借该类和实例调用

静态方法需要使用@staicmethod装饰器定义

静态方法和普通函数定义相同,不需要传入self示例参数和cls类参数

19.2 说明:

   类实例和对象实例都可以调用静态方法

   静态方法不能访问类变量和实例变量

19.3 示例:

class Myadd:

 

    @staticmethod

    def myadd(a, b):

        return a + b

 

 

print(Myadd().myadd(100, 200))

执行结果

300

20 实例方法,类方法,静态方法总结:

   不想访问类变量的实例变量(属性),用静态方法 (其实静态方法也可以定义在模块内,class外)

   只想访问类内变量,不想访问实例属性用类方法

既想访问类内变量,也想访问实例变量用实例方法

21 特性属性 @property

21.1 定义

Ø  用来模拟一个属性

Ø  通过@property装饰器可以对模块属性赋值和取值加以控制

Ø  实现其他语言的所拥有的getter和setter功能

21.2 示例

import math

 

 

class Circle:  # 圆类

 

    def __init__(self, r):

        self.radius = r   # 半径

 

    @property

    def area(self):

        return math.pi * self.radius ** 2

 

    @area.setter

    def area(self,a):

area函数经@property装饰器后伪装成了变量

 
        self.radius = math.sqrt(a/math.pi)   #属性赋值

 

 

又经过@area.setter装饰器后可以赋值,相当于把值传给了a形参、进而调用了 def area(self,a):函数,返回一个self,并且已经改变self对象的半径

 
c1 = Circle(10)

  

print(c1.area)      #314.1592653589793

c1.area = 31415.926

print(c1.radius)    #99.99999914709194

print(c1.area)      #31415.925999999996

 

 

示例2

# 1.写一个正方形类:

#     有三个属性:

#     边长是:length

#     周长: zhouchang

#     面积:area

# 要求:用此类生成对象,此三个属性中一个变化,其他属性同步变化(特护属性@property)

import math

这是装饰器另外一种用法

 
 

 


class zhengfangxing:

 

    def __init__(self, l):     

        self.length = l

 

    @property

    def area(self):

        return self.length ** 2

 

 

    @area.setter

    def area(self, a):

       self.length = math.sqrt(a) 

 

    @property

    def zhouchang(self):

        return self.length*4

 

    @zhouchang.setter

    def zhouchang(self,z):

        self.length = z/4

 

zfx1 = zhengfangxing(5)

print(zfx1.area)

print(zfx1.zhouchang)

zfx1.area = 36

print(zfx1.zhouchang)

 

print(zfx1.length)

22 id函数对象相关函数

id(obj) 返回对象的表识id (identity)