码迷,mamicode.com
首页 > 编程语言 > 详细

python学习第18天----属性、类方法、静态方法

时间:2020-10-29 09:48:18      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:person   key   object   rgba   重写   origin   使用场景   let   自动   

1.属性

引:计算一个人的MBI值

技术图片
class People:
    def __init__(self,name,weight,hight):
        self.name = name
        self.__weight = weight
        self.__hight = hight
    def EX(self):
        result = self.__weight/(self.__hight**2)
        print("%s的BMI值为%s"% (self.name,result))
p1 = People("Tom",60,1.75)
p1.EX()
输出:
Tom的BMI值为19.591836734693878
View Code

问题:对于如上程序虽然实现了功能,但是BMI值是一个名词(就应该封装到属性中),但是上述程序是通过一个方法计算出来的,相当于一个动词

1)属性:将一个方法伪装成一个属性,在代码的级别上没有本质的提升,但是让其看起来更加合理了

2)使用:在方法前加上@property这个装饰器,修饰方法,那么这个方法在调用时就不需要加括号了

技术图片
class People:
    def __init__(self,name,weight,hight):
        self.name = name
        self.__weight = weight
        self.__hight = hight
    @property
    def EX(self):           #伪装成属性
        result = self.__weight/(self.__hight**2)
        print("%s的BMI值为%s"% (self.name,result))
p1 = People("Tom",60,1.75)
p1.EX    
输出:
Tom的BMI值为19.591836734693878
View Code

3)将一个方法伪装后的属性改值

#如果在类中被@property @方法名.setter装饰器修饰的方法都存在,然后对被伪装的属性改值,那么就会自动执行被@方法名.setter修饰的方法,并且将要改的值传给被@方法名.setter装饰器修饰的方法的self参数后的参数

技术图片
class People:
    def __init__(self,name,weight,hight):
        self.name = name
        self.__weight = weight
        self.__hight = hight
    @property
    def EX(self):           #伪装成属性
        result = self.__weight/(self.__hight**2)
        print("%s的BMI值为%s"% (self.name,result))
    @EX.setter
    def EX(self,a1):
        print(a1)
        print("自动被执行。。。")
p1 = People("Tom",60,1.75)
p1.EX = 18                       #不需要括号,直接调用
输出:
18
666
View Code

技术图片

注:若要改属性的值,两个装饰器缺一不可

#例:修改被伪装的属性的值

技术图片
class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age

    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,a1):
        if type(a1) is int:
            self.__age = a1
        else:
            print("你输入的值有误")
p1 = Person("阿狸",18)
print(p1.age )
p1.age = 20
print(p1.age)
输出:
18
20
说明:首先实例化一个对象,传进去阿狸和18,实例化时自动执行__init__方法,执行时封装了一个名字name;p1.age让别然看来调用的就是p1对象的属性,@procerty就是将age方法伪装成一个属性,然后通过p1.age相当于执行age方法,返回__age私有变量值;p1.age = 20是对属性进行改变,只要值一改变就会自动的执行被@age.setter修饰的方法,并且将要改变的值传给方法的第二个参数
View Code
4)删除被伪装的属性【方法名.delerter
技术图片
class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age

    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,a1):
        if type(a1) is int:
            self.__age = a1
        else:
            print("你输入的值有误")
    @age.deleter
    def age(self):
        print("使用del,自动被执行..")
del self.__age           #删除私有变量
p1 = Person("阿狸",18)
print(p1.age )
del p1.age
输出:
18
使用del,自动被执行..
View Code
总结:可理解为一个执行触发一个方法

5)使用场景:property用于类似于求BMI这种,看似是一个名词,但是实际需要计算的,都用property装饰

2.类方法

#通过对象调用类的普通方法,会将对象地址传给普通方法的参数self

技术图片
class A:
    def func(self):     #普通方法
        print(self)
a1 = A()
a1.func()   #通过对象调用普通方法
A.func(a1)  #通过类名调用普通方法
输出:
<__main__.A object at 0x0000025F5AB75EB8>
<__main__.A object at 0x0000025F5AB75EB8>
View Code
1)类方法:就是在普通方法前,通过装饰器@classmethod修饰,再通过类名调用的方法,类方法种第一个参数约定俗成为cls,python自动将类名(类空间)传给cls
技术图片
class A:
    @classmethod
    def func(cls):   #类方法
        print(cls)
A.func()
输出:
<class __main__.A>
View Code

#如果是对象调用类方法,cls得到的是类本身

技术图片
class A:
    @classmethod
    def func(cls):   #类方法
        print(cls)
a = A()
a.func()
输出:
<class __main__.A>
View Code

2)类方法应用场景

①类中有些方法是不需要传入对象的,即不要对象的一起东西

#对于如下程序,完全不需要实例化对象,但是直接用类名调用函数会出错,需要再类名调用函数时传参

技术图片
class Person:
    name = "阿狸"
    age = 18
    def func(self):
        return Person.name+str(Person.age)
print(Person.func(1))
p = Person()
print(p.func())
输出:
阿狸18
阿狸18
View Code

#通过类方法时,不再需要创建对象

技术图片
class Person:
    name = "阿狸"
    age = 18
    @classmethod
    def func(cls):
        return cls.name+str(cls.age)
print(Person.func())
输出:
阿狸18
View Code

②对类中的静态变量进行改变时,要用到类方法

技术图片
class Person:
    name = "阿狸"
    age = 18
    @classmethod
    def func(cls):
        return cls.name+str(cls.age)     #就不再通过【类名.变量】的方式去改变静态变量
print(Person.func())
输出:
阿狸18
View Code
③继承中,父类得到子类的类空间(父类可对子类的所以内容进行修改)
技术图片
class A:

    @classmethod
    def func(cls): #类方法
        print(cls)      #父类中得到了子类的类空间
        print(cls.age)
class B(A):
    age = 22
    def func_b(self):
        pass
B.func()          #子类调用方法,先在子类找,子类找不到,去父类找,父类就得到了子类的类空间
输出:
<class __main__.B>
22
View Code
3.静态方法

1)通过装饰器@staticmethod修饰的方法,不需要给方法传递任何的参数,即相当于在类中定义了一个普通函数,不需要传递对象、类等参数

技术图片
class A:
    @staticmethod
    def func():       #静态方法
        print(666)
A.func()
输出:
666
View Code

2)静态方法优点

①在整体代码解构来说,使用静态方法(将方法写到类中)比较清晰,是一个代码块

②静态方法可提高代码的复用性

4.python2.xpython3.x的区别

1python2.x:各种大牛按照自己代码的习惯给python贡献源码(java的源码习惯,C#源码的小习惯),导致源码混乱,重复

python2.x中的输出是print()  print

python2.x中的range就是一个列表[1,2,3]

python2.x中的输入时raw_input(); input()只允许输入数字

模块、项目等等区别

2python3.x:龟叔重写,源码优美、清晰、简单,2020python2.x不再更新

python3.x中的输出是print()

Python3.x中,range是一个可迭代对象

python中的输入是input()

模块、项目等等区别

 

3)将一个方法伪装后的属性改值

           如果在类中被@property @方法名.setter装饰器修饰的方法都存在,然后对被伪装的属性改值,那么就会自动执行被@方法名.setter修饰的方法,并且将要改的值传给被@方法名.setter装饰器修饰的方法的self参数后的参数

python学习第18天----属性、类方法、静态方法

标签:person   key   object   rgba   重写   origin   使用场景   let   自动   

原文地址:https://www.cnblogs.com/piaolaipiaoqu/p/13890405.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!