美文网首页
【第29天】python全栈从入门到放弃

【第29天】python全栈从入门到放弃

作者: 36140820cbfd | 来源:发表于2019-08-20 11:56 被阅读0次

今天的主要内容是面向对象汇总

1.type(obj) obj是一个对象,那么type它就得到它的类型。 type(对象)的结果是对象实例化之前对应的类,type(类)结果是type。

代码块
class Student:
    pass

s=Student()
print(type(s))    #<class '__main__.Student'>
print(type(Student))    #<class 'type'>

类名+()就是一个实例化

new()创造了一个对象的空间,一些简单的初始化

2. type是所有类的元类,object是所有类的父类

类也是被创建出来的,type创建类, type(类名) =type

代码块
from abc import  ABCMeta
class A(metaclass=ABCMeta):
    pass

a=A()
print(type(a))
print(type(A))  #ABCMeta创建了这个A类,那么ABCMeta就是A的元类

# 如果没有指明ABCMeta,那么 type就是这个类的 元类

# type(类)的结果就是创建这个类的元类,大多数情况下就是type,除非你指定metaclass
代码块
class Saler:

    def __init__(self,name,sex,ident):

        self.name = name

        self.sex = sex

        self.ident = ident

    def sale(self):

        print('%s卖东西'%self.name)

    def add_goods(self):

        pass

alex = Saler('alex',None,'looser')

print(type(alex))  #Saler

print(type(Saler))  #type

3 什么时候使用面向对象?

python当中一切皆对象 基础数据类型 都是对象

类型和自定义类的关系 类型和类是一个东西

代码量大,功能比较复杂,角色多的时候,比如(qq 好友 陌生人 群 组

复杂的电商程序

公司/学校的人事管理/功能的系统

4 面向对象的好处

我的代码的清晰度更高了

可读性 无论是开发者 还是调用者 都能明确的分辨出每个角色拥有的方法和属性

增强了代码可扩展性

增加复用性

更加规范

5 类是什么时候被加载的,以及类名是什么时候生效的?

类从一创建就被加载,但是类中的函数只用调用才执行。

代码块
class Person:
    ROLE='student'
    # print(Person.ROLE)   name 'Person' is not defined
    print(ROLE)

    def func(self):
        print('我是一个函数')
        return 'bye'

p=Person()
print(Person.func)     #<function Person.func at 0x037C94B0>
print(p.func())    #我是一个函数      bye

思考5.1:为什么print(Person.ROLE)会报错?

因为这个时候class类还没有加载完成,只有加载完成才会有Person,此时还不存在,所以报错。

思考5.2:为什么Person.func和a.func两个内存地址不一样?

a.func指向class.func的地址,所以不一样。

6 对象与组合

对象

对象:类实例化对象的过程,就是构造new,初始化init

对象可以通过指针找到类的空间中的内容,指向类

对象本身存储了一些只属于对象的属性

组合

组合:一个类实例化对象作为另外一个类对象的属性就是组合

7 单继承(单继承子类调用父类方法)

代码块
class Foo:

    def __init__(self):

        self.func()

    def func(self):

        print('Foo.func')


class Son(Foo):

    def func(self):

        print('我是儿子')

s = Son()   #先执行父类的__init__(),再执行self.func()

子类有,父类没有,调用子类的

子类没有,父类有,调用父类的

子类有,父类也有,调用子类的

子类有,父类有,想调用父类,怎么办:

super().父类方法(参数)参数里面不用传self

父类名.父类方法(self,其它参数)

8 多继承的继承顺序

代码块
class A:

    def func(self):

        print('A')

class B(A):

    def func(self):

        super().func()

        print('B')

class C(A):

    def func(self):

        super().func()

        print('C')

class D(B,C):

    def func(self):

        super().func()

        print('D')

d = D()

d.func()  #ACBD  广度优先

b= B()

b.func()  #   AB

print(D.mro())  #[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
#类的继承顺序是DBCA

新式类(度优先 - C3算法)和经典类

代码块


mro方法查看继承顺序

py3 默认继承object  所以py3都是新式类

super().func() 遵循mro算法,在类的内部不用传子类名和self

py2 需要主动继承object,默认不继承

super(子类名,self).func() 必须传子类名和self

经典类 : 深度优先

py2 不继承object,默认都是经典类,也可以手动继承object,没有mro

9 多态(一种类型的多种形态 多个子类去继承父类,那么每一个子类都是这个父类的一种形态)

10封装

广义的封装 : 把方法和属性都封装在一个类里,定义一个规范来描述一类事物.

狭义的封装 : 私有化 只能在类的内部访问

__静态变量,私有方法 ,私有的对象属性,私有的类方法,私有的静态方法

在内存中存储 类名_名字

为什么在类的内部可以使用双下划线访问 : 在类的内部使用,你就知道你在哪个类中

在子类中可以访问访问父类的私有变量么?不行

私有 : 不能在类的外部使用也不能被继承

11 property的使用(把方法伪装成属性)

property装饰器函数,内置函数,帮助你将类中的方法伪装成属性,特性

调用方法的时候不需要主动加括号

让程序的逻辑性更合理

代码块
class A:
    def __init__(self, name):

        self.__name = name


    @property
    def name(self):

        return self.__name

    @name.setter
    def name(self, new_name):
        self.__name = new_name

    @name.deleter
    def name(self):
        del self.__name

a = A('alex')
a.name = 123
print(a.name)

# del a.name  # 语法
# #
# print(a.name)

@方法名.setter

(self,变量,新的值)

装饰器,修改被property装饰的属性的时候会调用被这个装饰器装饰的方法,除了self之外还有一个参数,被修改的值

@方法名.deleter

装饰器,当要删除被property装饰的属性的时候会调用被这个装饰器装饰的方法

12类方法classmethod(通过类调用,不通过对象)

代码块
class Goods:

    __discount = 0.8

    def __init__(self,price):

        self.__price = price

    @property

    def cost(self):

        return self.__price * Goods.__discount

    @classmethod

    def change_discount(cls,num):

        cls.__discount = num

Goods.change_discount(10)  #不用通过对象,通过类名就可以直接调用

a=Goods(5)

print(a.cost)  #50

13静态方法

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

相当于一个普通的函数

但是你由于某种原因,还要把这个方法放在类中,这个时候,就将这个方法变成一个静态方法

某种原因:

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

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

14反射

反射 - 从某个指定的命名空间中,用字符串数据类型的变量名来获取变量的值

类名反射: 静态属性 类方法 静态方法

对象反射 :对象属性 方法

模块 : 模块中的方法

代码块
import  sys
class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.school='北京大学'

    def study(self):
        print('%s%s在%s上大学'%(self.name,self.age,self.school))

res=sys.modules['__main__']
s2=getattr(res,'Student')('alex',18)   #实例化


s2.study()
getattr(s2,'study')()
# s2.study()与getattr(s2,'study')()是同一个
print(s2.study==getattr(s2,'study'))   #是同一个东西

15 双下方法(内置方法/魔术方法/双下方法)

代码块
__名字__不是被直接调用的

间接调用 : 内置函数/面向对象中特殊语法/python提供的语法糖

__str__ : str(obj),要求必须实现了__str__,要求这个方法的返回值必须是字符串str类型

print %sstr

__call__  : 相当于 对象()  用类写装饰器

__len__ : len(obj),要求obj必须实现了__len__,要求这个方法的返回值必须是数字int类型

__new__ : 在实例化的过程中,最先执行的方法,在执行init之前,用来创造一个对象,构造方法

__init__  : 在实例化的过程中,在new执行之后,自动触发的一个初始化方法,每个对象都会自动执行这个方法,没有就去父类中找__init__

16语法糖

代码块
x=5

y =6

print(x.__add__(y))   #11

print(x+y)# 语法糖  11
代码块
class MyType:

    def __init__(self,s):

        self.s = s

    def __add__(self, other):# __sub__ __mul__ __div__

            return self.s.count('*') + other.s.count('*')

obj1 = MyType('asjkfhk***17264****')

obj2 = MyType('asjkfhk***17***')

print(obj1.__add__(obj2) )    #13

print(obj1 + obj2)   #语法糖

17 str和repr区别

name='wangsiyu'
print(name) #wangsiyu 一个没有引号
print(repr(name)) #'wangsiyu' 一个有引号

代码块
__str__: str(obj)

要求必须实现了__str__,要求这个方法的返回值必须是字符串str类型

print %s     str

__repr__: 是__str__的备胎.如果有__str__方法,那么# print %s str都先去执行__str__方法,并且使用__str__的返回值

如果没有__str__,那么print %s str都会执行repr

repr(obj),%r

代码块
class A:

    def __init__(self,name):

        self.name = name

    def __str__(self):

        return '**%s**'%self.name

    def __repr__(self):

        return self.name

class B(A):

    def __init__(self,name):

        self.name = name

    def __repr__(self):

        return '***'

b = B('alex')  #实例化一个B类
print(str(b),repr(b))   #**alex** ***

print('%s | %r'%(b,b))  #**alex** | ***

print('---%r---'%('abc'))    #r代表repr

print('---%s---'%('abc'))    #s代表str

在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就执行父类的__str__

但是如果除了object之外的父类都没有__str__方法,就执行子类的__repr__方法,

如果子类也没有,还要向上继续找父类中的__repr__方法.一直找不到 再执行object类中的__str__方法

18内置方法

代码块
abs()

dict()把一个数据转为字典

help()

min()取出列表最小

bool()有就是True,没有就是False

dir()打印当前所有变量

hex()将一个数字转为16进制

sorted()排序

ascii()

oct()转为8进制

bin()转为2进制

eval()把字符串转为数字计算

ord()返回ACSII表位置

chr() 和ord()正好相反

map() reduce()  filter()

callable() 是否可以被调用

tuple()转为元祖

别跑,点个赞再走

相关文章

网友评论

      本文标题:【第29天】python全栈从入门到放弃

      本文链接:https://www.haomeiwen.com/subject/vodusctx.html