Python面向对象类方法、静态方法和property装饰器以及多类继承

总结一下:

实例方法:可以获取类属性、构造函数定义的变量,属于 method 类型。只能通过实例化调用。

静态方法:不能获取类属性、构造函数定义的变量,属于 function 类型。两种调用方式:类.方法名 ,实例化调用。

类方法 :可以获取类属性,不能获取构造函数定义的变量,属于 method 类型。两种调用方式:类.方法名 ,实例化调用。

classmethod能够完成的功能有:
  • 修改类中的变量,不论是类变量还是类实例传入的参数变量
  • 产生类实例,即装饰有classmethod的函数能够产生类实例(可能会有点懵,看看例子就明白啦)

修改类变量的例子:

class Worker:

    raise_percent = 1       # 默认没有涨工资,比例为1

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        
    @classmethod            # 加入此装饰器
    def ch_raise_percent(cls, num):        # 修改涨薪比例的函数
        cls.raise_percent = num * cls.raise_percent   # 传入一个数乘以之前的涨薪比例
    '''
    这里要多解释一下,传入的是cls,这里cls代表类本身。要传入类本身才能够修改类本身的内容(如类变量),
    由于传的是类本身,使用class的话会与class定义语句有冲突,因此使用classmethod要传入类的信息时,
    将类本身以cls形式传入。
    后面传入的num是在调用这个函数(即ch_raise_percent)时传入的参数,这个参数和创建类实例需要的
    参数是没有关系的,因为调用这个函数仅仅是修改了类本身的信息。
    '''
        
Worker.ch_raise_percent(1.3)   
# 这里在类外部调用classmethod装饰的函数,并传入一个num参数用于修改涨薪比例
print(Worker.raise_percent)
# 使用类本身查看其类变量是否变化

# 执行结果为1.3,表示这里我们确实把Worker类的raise_percent类变量给修改了。

有人可能会想使用其它方式不能直接修改类变量吗,比如在类函数中传入self,然后调用类变量(即self.raise_percent)来进行修改,但是实际上你在类函数中调用后修改产生的是局部变量,整个类是获取不到你修改得到的局部变量的。当然还有可能你会想使用global或者nonlocal(如global self.raise_percent或者self.raise_percent)等方法使函数产生的结果变成非局部变量,这个我也试了,好像是不行的。

产生类实例的方法:

产生类实例的方法真的是非常好用啊,比如你的初始数据是一堆有规则的字符串,而这些字符串中包含着每个类实例所需的参数,那么你只需要添加一个classmethod装饰的函数,用这个函数帮你处理一下你的字符串,将这些字符串分成独立的项,再将这些项传递给类就可以产生类实例啦!

class Worker:

    def __init__(self, name, age, height, salary):
        self.name = name
        self.age = age
        self.height = height
        self.salary = salary
    
    @classmethod
    def str_handler(cls, string):
        name, age, height, salary = string.split('/')  
        # 将传入的字符串以/分割产生列表,一一对应
        return cls(name, age, height, salary)
        # 这里return返回的就是cls,也就是一个类实例,将Worker类类实例需要的
        # 所有项都传入了cls,这就是一个完完整整的类实例啦
        # 要注意return返回值可以被变量接收,接收后就成为类实例咯
    
A = 'Jack/20/1.75/1000'   
B = 'Mary/18/1.65/2000'
# 两个需要处理的字符串

a = Worker.str_handler(A)
b = Worker.str_handler(B)
# 两次调用此类中的函数,产生两个类实例即a和b

print(a.name, a.age, a.height, a.salary)
print(b.name, b.age, b.height, b.salary)
# 查看类实例是否创建成功

在这里插入图片描述

staticmethod

staticmethod也叫静态方法,实际上staticmethod装饰的函数的功能可能和类本身没什么太大的关系,因为staticmethod装饰的函数不能传入类实例或者类变量或者刚刚提到的cls。因此这个函数处理的功能只是额外的,比如帮你记录一下日期之类的功能。这样的功能可能在某些时候会用上,所以就把这样的函数也顺带包装在类中。看一个例子就明白啦:

class Worker:

    def __init__(self, name, age, height, salary):
        self.name = name
        self.age = age
        self.height = height
        self.salary = salary
    
    @classmethod
    def str_handler(cls, string):
        name, age, height, salary = string.split('/')
        return cls(name, age, height, salary)
        
    @staticmethod           # 静态方法装饰器
    def read_file(worker_file):
        f = open(worker_file,'r')
        lines = f.readlines()
        return lines
    # 这里的功能就是读取工作人员的记录文件,将每一行内容作为一个item
    # 记录到lines列表,最后将列表传出以供后续利用
    # 有没有留意到,这个和类本身的功能是没有关系的,也就是实际上我们在类外部执行这个函数
    # 或者单独执行这些代码也是一样的功能,只不过包装在类中更便于管理和使用而已
    
all_workers = Worker.read_file('2020_workers.txt')  
# 使用上面的静态方法读取一个文件,这里假设有这个“2020_workers.txt”文件,其中每行都是
# Jack/20/1.75/1000 这样的内容
for item in all_workers:
    worker = Worker.str_handlerhandler(item)
# 通过for循环可以将文件中所有行都转为类实例
# 后面对类实例的操作就不写啦

静态方法的内容较简单,就不多写啦。

property

相对来说property装饰器的使用可能较复杂一点,property的翻译就是属性,因此其跟属性有关啦。而装饰器又是用来装饰函数的,那其实加property装饰器的功能就是将函数的返回值作为类的属性啦。什么意思呢,也就是说我们调用这个被装饰的函数不需要加括号去运行,而是直接像变量或者属性一样获取这个值。

看下例子吧:

class Worker:

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        
    @property
    def name_and_salary(self):
        return self.name+'的工资是'+str(self.salary)
    # 需要有返回值,返回值作为获取到的属性嘛

A = Worker('Jack',1000)
A.name_and_salary
# 注意这里不用加括号哦,像变量或者属性一样去调用就好了

现在应该理解property的作用了吧,当然property不止这点作用,使用property装饰后,被装饰的函数就成为了新的装饰器,新的装饰器常用的有三个,如上例中就是getter(默认的,即赋予类使用者获取某属性的能力)、setter(赋予类使用者在类外部给某类属性重新赋值的能力)和deleter(赋予类使用者在类外部删除某属性的能力)。看下例子就理解啦:

class Worker:

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    @property     
    # 先使用property装饰原函数,装饰之后就可以使用setter和deleter方法来进行装饰并有更多的功能了
    # 这里默认已经有了getter的功能,也就是能够获取到这个属性的能力
    def view_salary(self):
        return self.salary

    @view_salary.setter
    # setter装饰器能够使我们在类外部重新设置view_salary这个属性
    # 而没有setter的话就会报错  AttributeError: can't set attribute
    def view_salary(self, new_salary):
        self.salary = new_salary
        return new_salary

    @view_salary.deleter
    # deleter装饰器的设置使我们可以在类外部使用del删除这个属性,但是这里我试了将self.salary
    # 设置为其它值也是可以的哦,这个值设置非空的话还是会有属性继续存在的哦。也就是在类外部使用
    # del的功能取决于你自己在这里设置的操作
    # 我这里是设置为空值了
    def view_salary(self):
        self.salary = None

A = Worker('J',1000)

A.view_salary = 2000
# 这里在外部进行赋值,是使用的设置的setter方法哦,没有setter会报错的!!
print("使用setter后的view_salary 值是:"A.view_salary)

del A.view_salary  # 尝试删除
print("使用del后J 的view_salary 的属性值是:"A.view_salary)

在这里插入图片描述

Python同时继承多个父类有两种方法

1.使用未绑定方法逐个调用
2.使用super()函数。注意,这里有个特别要注意的地方,当子类继承于多个父类时,super() 函数只可用于调用第一个父类的构造函数,其余父类的构造函数只能使用未绑定的方式调用
class Employee:
    def __init__(self,salary):
        self.salary=salary
    def work(self, *args, **kwargs):
        print('普通员工在写代码,工资为:',self.salary)

class Customer:
    def __init__(self,favourite,address):
        self.favourite=favourite
        self.address=address
    def info (self):
        print('我是一个顾客,我的爱好是:%s,地址是%s'%(self.favourite,self.address))

class Mannager(Employee,Customer):
    def __init__(self,salary,favourite,address):
        print('Manngaer的构造方法')
        # 方法一:用未绑定方法来构造,使用类名直接构造,逐个调用
        # Employee.__init__(self,salary)
        # Customer.__init__(self,favourite,address)
        

        # 方法二:使用super()和未绑定方法
        super().__init__(salary)
        #与上一行代码效果相同
        # super(Mannager,self).__init__(salary)
        Customer.__init__(self,favourite,address)
m=Mannager(25000,'it产品','广州')
m.work()
m.info()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值