zoukankan      html  css  js  c++  java
  • 属性/类方法/静态方法

    主要内容:

    1.属性

    2.类方法

    3.静态方法

    一.属性


    属性(@property):将方法伪装成属性(将动词伪装成名词),代码上没有什么提升,只是更符合逻辑上的思想,更合理.

    配套装饰器:
    1,修改 @属性名.setter **
    2,删除 @属性名.deleter *

    属性的初识
    #需求一:求一个人的体质指数bmi
    #缺点:指数bmi是一个数值,传统意义上一般理解为名词,一般设置为静态变量,但代码的实现过程中将bmi作为动态变量来用了,不方便理解,不合理
    #改进:想办法把bmi当做属性来用(外部)
    #解决:使用@property 来把方法伪装成变量,代码无实质提升,但外部可以直接把bmi当做静态变量看待
    class Bmi:
        def __init__(self,name,hight,weight):
            self.name=name
            self.__hight=hight      #身高私有化
            self.__weight=weight    #体重私有化
        def bmi(self):
            bmi=round(self.__weight/(self.__hight**2),2)
            print("%s健康指数为%s" % (self.name,bmi))
    
    p = Bmi("小花", 1.75, 70)
    p.bmi()


    #需求二:将一个人实例化,将类中age()方法伪装成静态变量
    class Person:
        def __init__(self,name,age):
            self.name=name
            if type(age) is int:    #判断传入的年龄参数是否是int
                self.__age=age   #对象里自动封装成_Person__age
            else:
                print("您输入的年龄类型有误")
    
    
        @property     #年龄在一般人看来是静态变量,但是这里是方法,所以为了合理性,将age()函数调用伪装成age,执行的时候()不需要
                        #用到装饰器@property
        def age(self):
            return self.__age
    
    
        @age.setter    #修改年龄的时候,人家以为这是个静态变量,想在外部直接 对象.属性 直接修改,但这实际上是个方法,
                        # 所以修改的时候还需要继续伪装,继续用装饰器@属性名.setter,,
                        # 一遇到想要修改属性的操作,比如p.age=20,就自动执行装饰器@age.setter下面的方法
        def age(self,aa):     #修改年龄的值
            if type(aa) is int:    #判断修改的字符串是否是int
                self.__age=aa
            else:
                print("您输入的年龄类型有误")
    
    
        @age.deleter
        def age(self):
            del self.__age     # 删除对象中的age
    
    
    
    #普通版本(输出部分)
    
    #正确输入int类型的age
    p=Person("小花",18)
    print(p.age())
    
    #年龄不是int型,报错
    p=Person("小花","18")
    print(p.age())
    
    
    # 进阶版本
    # 年龄在思想上一般认为是名词,静态变量,但在上面是函数,调用的时候要使用   对象age()
    # 现在伪装一下,将方法伪装成静态变量,所以使用的时候直接是   对象.age
    
    #
    @property 是将一个方法伪装成属性,代码本身没有什么提升 # @方法名.setter 是用来修改伪装的方法(属性)的时候自动执行的 # @属性名.deleter 用来删除属性,自动执行
    #
    property的使用 : 类似于bmi这种,area,周长.... *** # @age.setter ** # @age.deleter * # 接上面的代码: #1.属性的修改 p=Person("小花",18) print(p.age) # 结果是18 # # 相当于print(p.age()),但这时候age()已经通过装饰器@property 伪装成了属性 p.age=20 # 用户想要修改年龄 # # 但age实际是一个方法,所以想改的时候必须再加一个装饰器@age.setter,在装饰器下面的age()方法中通过p.__age去修改 print(p.age) # 结果是修改后的结果20 #2.属性的删除 del p.age # 自动执行上面的装饰器@age.deleter

    二.类方法

    类方法(@classmethod): 通过类名调用的方法,类方法中第一个参数约定俗称cls,python自动将类名(类空间)传给cls.
    cls只接受类空间.
    # 类方法
    class A:
        def func(self):   #通过  对象.方法  引用,将对象名(对象空间)传给self
            print(self)
    
        @classmethod       #类方法,类本身可以直接调用
        def func1(cls):   #cla是类方法默认的参数,传进来的是类(类空间),谁(某个类)调用传谁的空间
            print(cls)
    
    #实例化一个A类的对象a1
    a1=A()
    #通过对象a1调用类的普通方法
    # 类不能直接调用自己的方法
    a1.func()   #<__main__.A object at 0x0000009AD39376D8> 此时self传入的是a1,也就是对象的空间
    #通过类调用类的普通方法,必须将对象作为参数传给self
    A.func(a1)   #<__main__.A object at 0x000000EB942F76D8>
                #如果想通过类名调用自己的普通方法,只有把自己的对象作为参数传给self,这样self接收的就是对象的空间
    
    #类调用自身的类方法,cls=A(类A的空间)
    A.func1()  #<class '__main__.A'>   类方法可以通过类名调用,传入的是类的空间
    #对象调用类的类方法,获得的是cls还是类本身,cls接收的是类的空间
    a1.func1()  #<class '__main__.A'>
    类方法的应用场景:
     1.类中有些方法不需要对象的参与.
    2.对类中的静态变量进行改变,要用类方法,类可以直接调用自己的类方法
    3.继承中,父类得到子类的类空间,对子类的变量修改
    # 场景1.类中有些方法不需要对象的参与.
    class A:
        name="alex"
        count=1
    
        @classmethod       #类方法
        def func(cls):   #想要得到"alex2",直接通过类就可以调用,不需要对象参与
            return  cls.name+str(cls.count+1)
    
    # A.func(1)  #报错  cls接收的是类空间,不能是1
    
    a1=A()
    #通过对象调用类的类方法
    print(a1.func())  #alex2
    #通过类调用类的类方法
    print(A.func())   #alex2
    # 场景2, 对类中的静态变量进行改变,要用类方法.
    class A:
        name="alex"
        count=1
    
        @classmethod
        def func(cls):
            cls.name="taibai"
            cls.count=2
    
    A.func()
    print(A.name)  #taibai
    print(A.count)  #2
    
    
    
    #场景3:继承中,父类得到子类的类空间,并可以任意修改子类空间的所有内容
    
    #(1)类通过访问自己的类方法,间接的修改子类空间的内容
    #错误的
    class A: name="alex" @classmethod def func(cls): print(cls) cls.age=20 return cls.age class B(A): age=10 print(A.func(B)) #报错 ,A.func(),cls默认接收的是A的类空间,但是后面又有一个参数,上面的func()里面没有多余的形参去接收 #如果想要print(A.func(B))执行
    #
    修改方法:(在func()方法中多增加一个参数)
    #正确的
    class A: name="alex" @classmethod def func(cls,b): #cls=B(类B的空间) print(cls) #<class '__main__.A'> b.age=20 #修改类B 的静态变量 return b.age class B(A): age=10 print(A.func(B)) #20

    需求:不通过类方法,想让我的父类的某个方法得到子类的类空间里面的任意值.
    方法:直接让子类的对象间接的调用父类的方法,把子类的对象的空间传给父类的方法,然后通过对象查看子类的任意值(不能修改)
    # 不通过类方法,想让我的父类的某个方法得到子类的类空间里面的任意值.
    class A:
        name="alex"
    
        def func(self):   #b1.func(), 所以func()中self的值是b1,也就是b1对象的空间
            print(self)    #<__main__.B object at 0x00000093BABE76D8>   #b1的内存地址
            print(self.age)  #22   #b1先在自己的对象空间里找,没有age,然后从自己的类B中找,找到了age=22
            self.age=18 #相当于b1.age=18  由于对象只能查看自己类中的内容,但不能修改,这一步相当于b1在自己的对象空间中增加了属性age=18
            print(B.__dict__)  #{'__module__': '__main__', 'age': 22, 'f1': <function B.f1 at 0x000000C3C76C9A60>, '__doc__': None}
                                #可以看出类B的空间里并没有修改age的值
            print(self.__dict__)#{'age': 18}   
                                #实际是在对象自己的对象空间里增加了age=18
            print(self.age)    #18     #对象b1从自己的空间里找到了age=18
    
    
    class B(A):
        age=22
    
        def f1(self):
            print(666)
    
    b1=B()   #实例化B类的对象b1
    b1.func()   #b1对象先在自己的空间里找func()方法,找不到,继续通过自己的类B找,也找不到.最后通过B类找父类B,找到func()执行
    
    # print(b1)    #<__main__.B object at 0x0000003986FF76D8>    #对象b1的内存地址
    # print(B)  #<class '__main__.B'>       #类B的内存地址

    三.静态方法

    静态方法:
        是指在类中的而某一个方法上加上@staticmethod
    作用:
      1.使代码块:清晰
      2.增加了代码的复用性

    总结: 静态方法主要是用来放一些方法,方法的逻辑属于类,但是又和类本身没有交互,从而形成了静态方法,主要是让静态方法放在此类的名称空间之内,从而能够更加有组织性。
      # 在定义静态方法的时候,和模块中的方法没有什么不同
      # 最大的不同就在于静态方法在类的命名空间之中,并且在声明静态方法的时候,使用的标记为@staticmethod,表示为静态方法
      # 在调用静态方法的时候,可以使用类名或者是实例名来进行调用,一般使用类名来进行调用

    静态方法和类方法的区别:
      1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数;
      2)从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量;
      3)静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法。

    class A:
    
        @staticmethod     #静态方法,可以不用传参
        def login(username, password):
            if username == 'alex' and password == 123:
                print('登录成功')
            else:
                print('登录失败...')
    
    A.login('alex',1234)
  • 相关阅读:
    基于设备的回声消除
    Libcurl细说
    抓包分析YY音频
    合唱音效解释
    EXCEL-COUNTIF()统计符合区间上的值个数
    EXCEL-对筛选出(单独手动隐藏行还是在统计范围内)的表格数据进行统计
    Perl字符串处理函数用法集锦
    Selenium-IDE,在网页上模拟人的操作
    Perl哈希%hash
    Perl if条件判断
  • 原文地址:https://www.cnblogs.com/mwj-blog1/p/9379172.html
Copyright © 2011-2022 走看看