58.基础语法-面向对象编程oop

  • 所有类都需要继承,若不指定继承的类,系统默认继承object系统默认类
  • 查询类中的元素用dir()
print(dir(object))

关于self

  • self.属性
    • 实力化之后的调用
    • self就是代表实例的名字
    • 若self.属性,调用后,方法中没有self.属性,则会向上找类的同名属性

__class__.类属性

  • 用这种方法调用,方法中想要用类的属性
class Lei():
    name = "lei_name"
    def fangfa(self):
        self.name = "fangfa_name"
        print(self.name)
        print(__class__.name)

a = Lei()
a.fangfa()
print(a.name)
print(Lei.name)

__init__构造函数

  • 在类实例化时自动执行,执行一些基础的初始化工作
  • 参数self必须有
  • 子类有构造函数,则父类的构造函数就不执行了
  • 若子类需要执行父类的构造函数,可以用super().__init__()调用
class gz():
    name = None
    age = 0
    def __init__(self):
        self.name = "菲"
        self.age = 38

g = gz()
print(g.name)
print(g.age)

面向对象的三大特征:继承,封装,多态

1.继承

  • 所有的类都默认继承object,这是系统默认的
  • 子类可以使用父类的内容,若成员与父类冲突,调用子类优先使用子类,不影响父类本身
  • 子类如果想扩充父类方法,可以在定义新方法的同时调用父类方法(类名.方法 或 super().方法),实现代码的复用
  • 父类,基类,超类 : 被继承的类

issubclass()

  • 可以检查某一个类是不是其他类的子类
class jc0():
    name = "a"
class jc1():
    name = "b"
    def f(self):             #父类方法
        print("我是父类的方法{}".format(self))
class jc3(jc0, jc1):
    def g(self):
        jc1.f(self)          #调用父类方法1
        super().f()          #调用父类方法2
        print("我是子类的方法")
jc4 = jc3()
print(jc4.name)
print(issubclass(jc3,jc0))
jc4.g()

super()

  • 用子类对象调用父类的方法和属性
class Father():
    def a(self):
        print("我是父类的方法")
class Son(Father):
    def a(self):  #子类的复写
        print("我是子类的方法")
su = Son()
su.a()
super(Son, su).a()

2.封装

  • 对对象的成员进行访问限制
  • 封装的三个级别:公开(public),受保护(protected),私有(private)

私有

  • 最高级别的封装,只能在当前类或对象中访问
  • 属性前加两个下划线“__”
  • PYTHON的私有本质是改了个名字,如果想,还是可以访问到的“_类名__私有元素名字”
class Fengzhuang():
    name = "python"
    __age = 1
print(Fengzhuang.name)
print(Fengzhuang._Fengzhuang__age)

受保护的

  • 在类中或子类中可以访问,在外部不可以访问
  • 成员前添加一个下划线“_”
  • 这种形式不是PYTHON硬性规定,而是大家公认的形式
class Shoubaohu():
    _name = "python"

公开的

  • 就是普通的定义成员

3.多态

  • 同一个对象在不同情况下以不不同的状态出现
  • 在python中多态是一种设计思想,不是语法

类的相关函数

issubclass()

  • 检测一个类时不时另一个类的子类
class A():
    name = "A"
class B(A):
    name = "B"
print(issubclass(B, A))

hasattr

  • 检测一个类或者对象,是否包括一个成员
a = A()
print(hasattr(a, "name"))

getattr

  • 获取对象的属性,如果没有该属性,返回预设值。
print(getattr(a, "name", None))

setattr

  • 修改对象内的属性,如果没有对象,会报错
s = A()
setattr(s, "name", 1)
print(s.name)

delattr

  • 删除类属性
d = A()
delattr(A, "name")

dir

dir(A)

property()

  • 对对象属性进行修饰操作,对属性进行相应操作(读取,修改,删除)时,触发相应方法进行修饰
  • 参数内顺序时固定的读,写,删除
class Pr():
    
    def __init__(self):
        pass
    def fget(self):
        return self._name * 2     #如果不加“_”会报递归深度报错
    def fset(self, name):
        self._name = name.upper() #upper()字符串大写,swapcase()字符串小写
    def fdel(self):
        self._name = "None"
    
    name = property(fget, fset, fdel, "对name属性进行修饰")

pro = Pr()
pro.name = "qwe"
print(pro.name)

常用的类的魔术函数

  • 不需要人为调用,只是在特定的时候触发的函数

操作类

  • __new__对象实例化的方法,我们一般不使用
  • __init__构造函数,初始化函数时候使用
  • __call__把对象当函数使用时候,调用此魔术函数
class Cy():
    def __init__(self):
        pass
    def __call__(self):
        print("我被当作函数调用了")
    def __str__(self):
        return "我被当作字符串调用了"

cy = Cy()
cy()
  • __str__当对象被当作字符串使用的时候,调用此魔术函数
print(cy)
  • __getattr__ 当调用对象属性不存在时,本该报错,但你希望触发相应的方法是使用
class Gta():
    name = "1"
    def __getattr__(self, name):
        print("没有你要找的属性{}".format(name))
    def __setattr__(self, name, value):
        print("你对{}进行了赋值操作".format(name))
        #self.name = value 如果用此种方法,会进入死循环,不断的自我调用
        super().__setattr__(name, value)

gt = Gta()
print(gt.dieiasdalssddsdf)
  • __setattr__ 对类的属性进行赋值时,自动触发
gt.name = "123"
print(gt.name)

描述符类

  • __set__() 调用一个属性时,触发
  • __get__() 为一个属性赋值时,触发
  • __delete__() 采用del删除属性时,触发
class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
    def __get__(self, instance, owner):
        print('__get__(),被执行了')
    def __set__(self, instance, value):
        print('__set__(),被执行了')
    def __delete__(self, instance):
        print('__delete__(),被执行了')

运算相关

  • 等等 用时候查看

类和对象的三种方法

  1. 实例方法

    • 需要实例化对象才能够使用
  2. 类方法

    • 不需要实例化,用类可以直接访问
    • 区别:可以对类的属性进行修改
  3. 静态方法

    • 不需要实例化
    • 区别:只能通过类调用
class ren():
    
    #实例方法,用self
    def chi(self):
        print(self)
        print("吃~~~~~~~!")
    
    #类方法,用cls
    @classmethod
    def he(cls):
        print(cls)
        print("喝~~~~~~~~~!")
    
    #静态方法,不用
    @staticmethod
    def wan():
        print("玩~~~~~~~~~~!")

h = ren()

#实例方法
h.chi()
#类方法
ren.he()
#静态方法
ren.wan()

抽象类

  • 定义:没有具体事项内容的方法的类,包括抽象方法的类
  • 意义:规范子类的行为接口,子类若要实例化,就必须实现父类的抽象方法
  • 抽象类的创建:借助 import abc 模块来实现
  • 特点:
    1. 可以包括抽象方法,也可以包括具体方法。
    2. 抽象类不允许实例化,只能被继承,继承后必须实现抽象,否则依然不允许实例化。
    3. 抽象类的作用就时设定类的标准,便于开发时,有统一的规范
import abc
class Humen(metaclass=abc.ABCMeta):
    
    #定义抽象方法
    @abc.abstractmethod
    def chi(self):
        pass

    #定义类的抽象方法
    @abc.abstractclassmethod
    def he(self):
        pass

    #定义静态抽象方法
    @abc.abstractstaticmethod
    def wan():
        pass

    #普通方法
    def le():
        print("乐~~~~!")
posted @ 2020-02-22 16:51  TK_tank  阅读(77)  评论(0编辑  收藏  举报