zoukankan      html  css  js  c++  java
  • python===属性--类方法

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

      伪装  一个属性 

    class  Person:

      def   _ _init_ _(self,name, weight,hight):

        self.name=name

        self.weight=weight

        self.hight=hight

      def  bim(self):

        return  %s的bmi为%s %(    self.name,    (   self.wejght   /   ( self.hight**2 )    )    )

    p1=Person("哈哈",50,1.63)     #   实例化一个对象

    p1.bmi ( )  #        这样直接调用类中的方法  可以得到  对象的bmi  

          但是 这样  得到的bmi  是当成函数方法运算出来的    ,    

          正常来说  bmi  是一个名词属性   因此  我们可以

            通过@property   装饰器将其伪装成一个属性  .

    通过@property   装饰器将其伪装成一个属性  :   

    class  Person:

      def   _ _init_ _(self,name, weight,hight):

        self.name=name

        self.weight=weight

        self.hight=hight

      @property     #   装饰器      将下列方法伪装成一个对象的属性

      def  bim(self):     

        return  %s的bmi为%s %(    self.name,    (   self.wejght   /   ( self.hight**2 )    )    )

    p1=Person("哈哈",50,1.63) 

    print( p1.bmi  )    ====>   得到  结果    #   对象名  .  属性    直接执行    

      但是若其中有一个年龄的参数  我们应该怎样去修改  其中的参数呢 ?      见下例子

     e.g  

      class  Person:

        def  _ _init_ _(self , name , age ) :

          self . name= name

        ##  self. _ _age = age      #   年龄 作为  私有成员    保密

          self. _ _age = age      if    type ( age )  is    int      else      print(    "    输入格式不对请输入数字   ")       

          #   这样写  是  用三元 运算法      写的   if   语句      

            让输入的数字必须是  数字类型的  ,  若不是的话 显示不是  

        @property     

        def  age(self):           #   设置一个  伪装  的属性  方法 

          return    self . _ _age      返回    self. _ _age     的值

        @age . setter      #    添加一个   可以对    属性  进行修改       age   伪装属性和更改的函数和装饰器中的  必须是 相       

        def  age(  self  ,  a1 ):     后边的   a1  接收的 是    要  更改的 age  参数          同的才可以

          self. _ _age = a1       if    type ( a1 )  is    int      else      print(    "    输入格式不对请输入数字   ")       

          #   这样写  是  用三元 运算法      写的   if   语句      

            让输入的数字必须是  数字类型的  ,  若不是的话 显示不是  

          print ( 666 )

        @age.deleter   #   删除

        def  age(self): 

          del  self._ _age    #   删除  self .age 

    p1=Person( "哈哈" ,  20  )    #  实例化对象   会自动执行  _ _init_ _传入参数   判断age  然后向下走

    p1.age=18      #     这样  是对 属性  进行 修改   

            当函数  执行到这一步时  会  先  执行  @age . setter  

               然后将后边的值   传说 给 a1   再向下判断 输入值 

    print  ( p1.age )   === > 18    666    最后结果是修改过的值

    del  p1.age     #  执行 删除  self._ _age      一有这个就会  触发  @age.deleter  

    print (p1._ _dict_ _)   == >  {  name: 哈哈  }

    类方法   

        :   通过  类名     调用的     类方法   ,   

          类方法中的第一个参数  是   cls  约定俗成  的     

          python   自动将  类名  即 类空间    传给 cls

        : 通过 对象 调用   类方法  

          传给     cls  的是    类本身

      class  A:

        def  func( self ) :

          print( self )

        @ classmethod        #   类方法

        def   func1 (  cls  ) :

          print ( cls )

    a1=A()

    a1.func()     #   相当于    对象名.方法   调用类中的方法  ===>     <__main__.A object at 0x00B10F50>

    A . func( a1 )   得到函数内存地址  工作中不常用           得到    内存地址

    a1.func1 ()     #  对象   调用类 中的  类方法  传入的是类本身  

          相当于     A() .  func1 ()  ===>   <class '__main__.A'>

                    得到的是  一个 类  A  的 类空间

    A.func1()     #   在有 类方法的  类中    

            类名 . 类方法()    相当于将类空间传递给了  类方法得第一个参数  

                因此得到   A的类   类空间   ===>   <class '__main__.A'>

    类方法的应用场景

      1.  类中有些方法 是不需要传入对象的  ,  不要对象的一切东西

    e.g

      class  A:

        name  = " alex "

        count=1

        def  func( self ) :

          return   A.name +  str(  A.count+1 )

    a=A()

    print(  a.func() )

       

      class A:
        name = "alex"
        count =1
        @classmethod
        def func( cls ):
          return   cls.name + str(cls.count+1)
    a=A()
    print(a.func())

      2.对类中的静态变量 进行改变时  要用类方法

    class   A:

      age=12

      @classmethod

      def  func( cls ):

        cls.age=20

    a=A()   实例化一个对象

    A.func()  将类空间传给cls   并将其中的  age  赋值为  20 

    print(A.age)===>    得到结果   20 

       

      3.继承中 父类得到子类的空间  

        在父类中类方法  得到子类的空间  并可以对其进行  任何操作

              对子类进行任何操作

      e.g  

      class A:  

        def  func(self):

          print(self )

        @classmethod

        def  func1( cls ) :

          print(cls)

      class  B(A):

        def  f1( self ):

          pass

      B.func1() ===><class '__main__.B'>     现在b类中找  func1  没有  ,  

              再到  A类中  找  有  B 类会传给  cls 

                  因为B类名  调用 类方法    因此得到的是  B的类空间

    class  A:

      age=12

      @classmethod        #类方法

      def  func( cls ):       #   将类空间传给  cls 

        cls.age=50      #     得到 类空间后   对类空间做改变   将B 中的   age  改为  50   

        str = "jjj "    #     得到 类空间后   对类空间做改变   将B 中的   str  改为  jjj   

        print( cls.age )

    class B(A):

      age=22

      str="dgg"

    B.func()    #   通过类名 + 类方法名   得到  类空间    

    print(   B.age   )  === >    50     

    print(  B.str  )  =====>   jjj

    普通的方法  

    class  A

      age = 12

      def  func2( self ):    #self  子类的对象也能得到子类的内容  但是不能改

        print( self )

    class  B(A)  :

      age=11

    b=B()

    print( b.age )

    静态方法  : 不需要  对象  ,不需要传参数  直接用的时候  就调用

      什么时候用? 

       1. 如果一个类里边的方法,  既不需要用到 self 中的资源也不需要 用cls中的资源

       2.    相当于一个普通函数

       3.    但  你由于某种原因   还要把这个方法放在  类中  这个时候  就将  这个方法变为  静态方法

          这个某种原因是什么?

            1.  完全想用面向对象编程 所有的函数都必须写到类里

            2.  某个功能确确实实是这个类方法 , 但是确确实实  没有用到和这个类有关系的资源  

    优点:   1.  在代码块观赏角度来说   静态方法比较清晰  

            和普通静态方法相比来说   ,  只是一个方法,  若写一堆方法放到一起,太乱不好找

            将其放到一个类中,  可以很快找到 然后直接通过类名就可以调用 

          2.  增加了代码的复用性

    class  A:

      @staticmethod

      def  func():

        print(666)

    A.func()===> 666

  • 相关阅读:
    初賽
    SA
    高斯-约旦消元法
    AC自动机
    KMP
    关于scanf
    网络流
    常用SQL语句
    Java开发中的23种设计模式详解(转)
    generatorConfig.xml
  • 原文地址:https://www.cnblogs.com/lynysy/p/9379329.html
Copyright © 2011-2022 走看看