python的面向对象、类方法和静态方法

一、面向对象

  • 是一种认识世界,分析世界的方法论,将万事万物抽象为类

1、类class

  • 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合,用计算机语言来描述类,就是属性和方法的集合

2、对象instance,object

  •  对象是类的具象,是一个实例
  •  对于我们每个人这个个体,都是抽象概念人类的不同的实体
  •  对象属性:它是对象状态的抽象,用数据结构来描述
  •  对象操作:它是对象行为的抽象,用操作名和实现该操作的方法来描述

3、面向对象三要素

  •  封装:将数据和操作组装到一起,起到隐藏数据,对外只暴露一些接口通过接口访问对象
  •  继承:多复用,继承来的就不用自己写了,多继承少修改,使用继承来改变,来体现个性
  •  多态:面向对象编程最灵活的地方,动态绑定
    举例:
        class Myclass:
            """A example class"""
            x = 'abc' #类属性
            
            def foo(self): #类属性也是方法
                return 'My Class'

4、类对象及类属性

  •  类对象,类的定义就会生成一个类对象
  •  类的属性,类定义中的变量和类中定义的方法都是类的属性
  •  类变量,x是类Myclass的变量

5、类的实例化

  •  a = Myclass()
  •  类实例化后获得的实例,是不同的实例,即使是使用同样的参数实例化,也得到不一样的对象
  •  python类实例化后,会自动调用__init__方法,这个方法第一个参数必须留给self

6、__init__方法

  •  Myclass()实际上调用的是__init__(self)方法,可以不定义,如果没有定义会在实例化后隐式调用
  •  作用是对实例进行初始化
  •  __init__()方法不能有返回值,也就是只能是None
举例:    
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def showage(self):
            print('{} is {}'.format(self.name,self.age))
    
    tom = Person('Tom',20)

7、实例对象instance

  •  类实例化后一定会获得一个对象,就是实例对象
  •  __init__方法的第一个参数self就是指代某一个实例
  •  类实例化出一个实例对象,实例对象会绑定方法,调用方法是采用tom.showage()方式
  •  这个self就是tom,python会把方法的调用者作为第一参数self的实参传入
  •  self.name就是tom对象的name,name是保存在了tom对象上,而不是在Person类上,所以称为实例变量

8、实例变量和类变量

  •  实例变量是每个实例自己的变量,是自己独有的;
  •  类变量是类的变量,是类所有实例共享的变量属性和方法
class Person;
        age = 3  # 类变量
        def __init__(self, name, age):
            self.name = name   # 实例变量
            self.age = age
print(Person.__class__)
print(sorted(Person.__dict__.items())  #属性字典
    
tom = Person('Tom',20)
print(tom.__class__)
print(sorted(tom.__dict__.items()))
上例中,可以看到类属性保存在类的__dict__中,实例属性保存在实例的__dict__中,如果从实例访问类的属性,就需要借助__class__找到所属的类

9、类和实例

  •  是类的,也是这类的所有实例的,其实例都可以访问到,是实例的就是这个实例自己的,通过类访问不到
  •  类变量是属于类的变量,这个类的所有实例可以共享这个变量
  •  实例可以动态的给自己增加一个属性,实例__dict__和实例变量都可以访问到
  •  实例的同名变量会隐藏这个类变量,或者说是覆盖了这个类变量

10、实例属性的查找顺序

  •  指的是实例使用点来访问属性,会先找自己的__dict__,如果没有,然后通过属性__class__找到自己的类,再去类dict中找
  •  注意,如果实例使用__dict__[变量名]访问变量,将不会按照上面的查询顺序找变量

二、类方法和静态方法

  •  前面的例子中定义的__init__等方法,这些方法本身都是类属性,第一个参数必须是self
  •  self必须指向一个对象,也就是类必须实例化之后,由实例来调用这个方法

1、普通函数调用

    class Person:
        def normal_method():
            print('normal')
    Person.normal_method() # 可以调用
    Person().normal_method()  #不能调用

    Person.normal_method()可以调用,因为这个方法只是被Person这个名词空间管理的一个普通方法
    normal_method只是Person的一个属性而已
    由于normal_method在定义的时候没有指定self,所有不能完成实例对象的绑定,不能通过实例化来调用
    

2、类方法

  •  在类定义中,使用@classmethod装饰器修饰的方法,必须至少有一个参数,且第一个参数留给了cls,cls指代调用者即类对象自身
  •  cls这个标识符可以是任意合法名称,但是为了易读,请不要修改
  •  通过cls可以直接操作类的属性
举例:
    class Person:
        @classmethod
        def class_method(cls):
            print('class = {0.__name__} ({0})'.format(cls))
            cls.HEIGHT = 170
    
    Person.class_method() 
    print(Person.__dict__)  

    >>> Person.class_method()
    class = Person (<class '__main__.Person'>)
    >>> print(Person.__dict__)
    {'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'HEIGHT': 170, '__dict__': <attribute '__dict__' of 'Person' objects>, 'class_method': <classmethod object at 0x00000000030783C8>}

3、静态方法

  •  在类的定义中,使用@staticmethod装饰器修饰的方法
  •  调用时,不会隐式的传入参数,静态方法只是表明这个方法属于这个名词空间
class Person:
        @classmethod
        def class_method(cls):
            print(11111,'class = {0.__name__} ({0})'.format(cls))
            cls.HEIGHT = 170
        
        @staticmethod
        def static_method():
            print(2222222,Person.HEIGHT)

Person.class_method()
Person.static_method()
print(333333333,Person.__dict__)

    类除了普通方法都可以调用,普通方法需要对象的实例作为第一参数
    实例可以调用所有类中定义的方法(包括类方法,静态方法),普通方法传入实例自身
    静态方法和类方法需要找到实例的类


 

原文地址:https://www.cnblogs.com/jiangzuofenghua/p/11413610.html