python学习第15节:面向对象编程(下)

发布时间:2020/07/15 作者:天马行空 阅读(1074)

一、类的方法
类体中的函数叫做方法。与类相关的方法有三种:静态方法、实例方法和类方法。

1.1、静态方法
在类体中,使用@staticmethod声明其下所定义的是一个静态方法。Python中以@开头的这个东西,我们称作装饰器。
对于功能的具体实现,静态方法和普通函数是完全一样的:使用def作为定义的开始,后面加上空格以及方法名。方法名之后,使用括号定义这个方法可以接收的传入参数。在括号之后,放上冒号。最后换行之后,加上空格递进,定义方法的具体实现逻辑。
在类体之外,跟访问类变量的方式类似,可以使用实例名.静态方法名(参数)或者类名.静态方法名(参数)的方式调用静态方法。
它其实是一个被塞到了类体中的独立的、单纯的函数,功能上跟普通函数几乎一样。它仅仅是托管于某个类的名称空间中,便于使用和维护。

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.name = name
        self.this_id = this_id
        self.password = password
        self.money = money
    @staticmethod
    def fun():
        print("我是一个静态方法")
BankAccount.fun()
tom_account = BankAccount("Tom", "123456", "666666", 1000)
tom_account.fun()


1.2、实例方法
实例方法是类体中最常见的方法。上一关讲的构造方法既是魔法方法(方法名前后各有两个下划线),又是实例方法。
实例方法,因其具有实例的个性化操作能力,通常用于对实例变量进行操作的场景之中。
下面我们来定义一个实例方法修改tom的银行密码:

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.name = name
        self.this_id = this_id
        self.password = password
        self.money = money
    # 定义了一个修改密码的实例变量
    def change_password(self, new_password):
        self.password = new_password
tom = BankAccount("Tom", "123456", "123456", 1000)
print("{}原来的密码是{}" .format (tom.name, tom.password))
tom.change_password("666666")
print("{}现在的密码是{}" .format (tom.name, tom.password))


1.3、类方法
类方法同类变量一样,可以对所有实例产生作用,可以被类和实例调用。
类方法的定义需要首先使用装饰器classmethod进行装饰,然后定义一个函数,函数的第一个参数应该是cls。
在语法上,类方法既需要类似静态方法的装饰器,又像实例方法那样,在方法参数的第一个位置需要加一个功能与self相似的东西,写作cls。cls是类的英文单词class的缩写。
类方法也可以使用实例名.类方法的方式调用。

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.name = name
        self.this_id = this_id
        self.password = password
        self.money = money
    @classmethod
    def change_interest_rate(cls, x):
        cls.interest_rate = cls.interest_rate + x
print("银行账户类原来的类变量interest_rate是{}" .format(BankAccount.interest_rate))
BankAccount.change_interest_rate(-0.01)
print("银行账户类现在的类变量interest_rate是{}" .format(BankAccount.interest_rate))

图片.png



二、类的封装性
封装性是类的三大特征之一,最直白的解释是:类或实例的一些变量和方法不能从外部进行访问和调用。

2.1、私有变量
通过实例名.变量名、类名.变量名的方式在类体之外读取或者设置变量的值。这种可以在类之外直接访问到的变量,通常叫做公有变量。
Python当中,如果想要使变量成为私有变量,只需要在变量名前加上双下划线__,就可以了。

2.2、私有方法
私有方法和私有变量一样,也是为了封装一些不想被外部访问的方法。它们的命名规则也是一样的,即私有方法也是在方法名之前加两个下划线。

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.__name = name
        self.__this_id = this_id
        self.__password = password
        self.__money = money
    def __get_money(self):
        return self.__money
    def get_name(self):
        return self.__name
    def authorize(self):
        money = self.__get_money()
        if money > 1000:
            return True
        else:
            return False
tom = BankAccount("Tom", "123456", "888888", 2000)
if tom.authorize():
    print('可以为{}提供分期付款服务'.format(tom.get_name()))
else:
    print('不能为{}提供分期付款服务'.format(tom.get_name()))
jerry = BankAccount("Jerry", "123457", "666666", 500)
if jerry.authorize():
    print('可以为{}提供分期付款服务'.format(jerry.get_name()))
else:
    print('不能为{}提供分期付款服务'.format(jerry.get_name()))


2.3、属性
类和实例的变量相对于普通程序变量来说,具有反映客观物质属性的功能,因此一般也称它们为属性。
在真正意义上的面向对象编程中,大部分的实例变量、类变量会被封装起来,不允许在类体外直接访问。
对于那些确实需要读取和修改的实例变量,我们使用公有的getter访问器(一个公有方法)进行获取,使用公有的setter访问器(一个公有方法)进行修改。

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.name = name
        self.__this_id = this_id
        self.__password = password
        self.__money = money
    def get_password(self):
        return self.__password
    def set_password(self, password):
        self.__password = password
tom = BankAccount("Tom", "123456", "888888", 1000)
print("{}原来的密码是{}" .format(tom.name, tom.get_password()))
tom.set_password("666666")
print("{}现在的密码是{}" .format(tom.name, tom.get_password()))


为了让私有变量可以被读取和修改,我们实际上是定义了两个实例方法get_password和set_password,然后调用这两个方法来读取和修改密码。
这里的get_password和set_password就分别是属性__password的getter访问器和setter访问器。

在定义getter访问器和setter访问器之前加上特殊的装饰器,就可以在类体外像使用公有变量一样直接对私有变量进行读取和修改了。

class BankAccount(object):
    interest_rate = 0.05
    def __init__(self, name, this_id, password, money):
        self.name = name
        self.__this_id = this_id
        self.__password = password
        self.__money = money
    @property
    def password(self):
        return self.__password
    @password.setter
    def password(self, password):
        self.__password = password
tom = BankAccount("Tom", "123456", "888888", 1000)
print("{}原来的密码是{}" .format(tom.name, tom.password))
tom.password = "666666"
print("{}现在的密码是{}".format(tom.name, tom.password))



上述代码首先使用了property装饰器进行修饰,然后定义了一个实例方法password(self),方法的实现逻辑中,直接将实例属性__password作为返回值return,跟之前的get_password方法相同。这就是getter访问器。


为了定义setter访问器,首先使用getter方法名称.setter(即password.setter)作为装饰器,然后定义setter的方法头部和函数体,方法中的实现逻辑跟之前的set_password一样,将方法调用时传入的参数赋值给私有属性__password。


在定义了getter跟setter之后,就可以像使用属性一样完成方法的调用操作。在例子中,当需要读取__password值的时候,使用tom.password的方式,它实际上是调用了getter方法tom.password()(注意:方法使用装饰器声明为getter之后不能再用方法调用方式触发)。


需要注意的是,getter访问器的定义需要放在setter访问器定义的前面。因为只有定义了getter之后,放在setter前的getter的方法名.setter装饰器才是有效的。

图片.png


总结
方法:类体中的函数称为方法,按照功能可分为静态方法、实例方法和类方法;按照封装性可分为私有方法和公有方法。
装饰器:本质上是个封装好的函数,作用是给其它函数加上固定特性或功能。
访问器:对私有变量进行操作的函数,常见的访问器有getter访问器和setter访问器。
getter和setter:对私有属性的特殊封装方式,可以使方法调用就像直接访问属性一样。
图片.png


练习:根据信用评级获取贷款额度

class AccountBank():
    def __credit_score(self):
        import random
        level = [1,2,3,4]
        return random.choice(level)
        
    def loan(self, year, money):
        self.score = self.__credit_score()
        print('你的信用评级为{}'.format(self.score))
        self.loan_rate = 0.05*self.score
        total_money = money*(1+self.loan_rate)**year
        return total_money
ab = AccountBank()
print('贷款额度为{}'.format(ab.loan(1,2000)))


关键字python python教程