昨日回顾

  • 反射

    • 用"字符串"类型的属性名/方法名来找到
    • 属性的值或者方法的内存地址
  • 所有可以反射的内容实际上都是变量 有内存地址
  • 内存地址存的是"具体的值",直接能取到结果
  • 内存地址存的是"函数\方法\类",取到的是内存地址
  • 有哪些东西你一打印打印出的是地址
    • 函数
    • 类中的各种方法

如何反射类

class Foo:pass
import sys
clas = getattr(sys.modules[__name__],'Foo')
print(clas)   # == Foo
obj = clas()   # Foo() 相当于实例化一个Foo对象的过程

如何反射函数

def func():print('12345')
import sys
func_addr = getattr(sys.modules[__name__],'func')
func_addr() # func()

如何反射变量

全局变量
a = {2,2,3}
import sys
b = getattr(sys.modules[__name__],'a')
print(b)

如何反射类里的成员

  • 类中的成员 : 静态变量 静态方法 类方法 对象方法 property方法
  • 习惯使用类调用的有哪些 : 静态变量 静态方法 类方法
  • 对象中的成员 : 对象属性
  • 习惯使用对象调用的有哪些:对象属性 对象方法 property方法
  • 类和对象中成员的反射 都是遵循"调用习惯"的
class Foo:
    Country = 'China'

    @classmethod
    def showCountry(cls):
        print('in showCountry',cls.Country)

    @staticmethod
    def wahaha():
        print('wahaha')
#类中的静态属性
print(getattr(Foo,'Country'))

类中的类方法

print(getattr(Foo, 'showCountry'))   # Foo.showCountry
getattr(Foo, 'showCountry')()   # Foo.showCountry()

类中的静态方法

getattr(Foo, 'wahaha')()   # Foo.wahaha()

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def eat(self):
        print(self.name + ' is eating')

alex = Student('alex',84)
print(getattr(alex,'name'))   # alex.name
print(getattr(alex,'age'))   # alex.age
getattr(alex,'eat')()    # alex.eat()
import time
import re
import os
import sys
import random
import json
import pickle
import collections
import hashlib

lst = [1,2,3,4,5]
random.shuffle(lst)
print(lst)

getattr(random,'shuffle')(lst)
print(lst)

isinstance(对象,类) 判断对象是不是这个类或者这个类的子类的对象
issubclass(类1,类2) 判断类1是不是类2的子类

内置方法

  • 90%
  • 内置方法 双下方法 魔术方法
  • 都是python的对象内部自带的
  • 并且都不需要我们自己去调用它

str

repr

class Course:
    def __init__(self,name,price,period):
        self.name = name
        self.price = price
        self.period = period
    def __str__(self):
        '''打印这个对象的时候 自动触发__str__'''
        '''使用%s进行字符串的拼接的时候 自动触发__str__'''
        return '%s,%s,%s'%(self.name,self.price,self.period)

python = Course('python',25000,'6 months')
print(python)
print('course %s'%python)
print(f'course {python}')
#如果 不实现str方法,那么对象打印出来只是一串地址
l = [1,2,3]
#l是对象,打印的时候直接显示的是元素
print(l)
class Course:
    def __init__(self,name,price,period):
        self.name = name
        self.price = price
        self.period = period

    def __repr__(self):   # 备胎
        return '%s,%s,%s'%(self.name,self.price,self.period)

    def __str__(self):
        return self.name

python = Course('python',25000,'6 months')
print(python)
print('course %s'%python)
print(f'course {python}')
print(repr(python))
print('course %r'%python)

如果str存在,repr也存在

  • 那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
  • 而repr(obj)和%r格式化字符串,都会调用__repr__

如果str不存在,repr存在

  • 那么print(obj),字符串格式化format,%s,%r 和repr(obj)都调用__repr__

如果str存在,repr不存在

  • 那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
  • repr(obj)和%r格式化字符串 都会打印出内存地址
class Course(object):
    def __init__(self,name,price,period):
        self.name = name
        self.price = price
        self.period = period

    def __repr__(self):   # 备胎
        return '%s,%s,%s'%(self.name,self.price,self.period)

    # def __str__(self):
    #     return self.name

class Python(Course):
    pass
    # def __repr__(self):   # 备胎
    #     return '%s--%s--%s'%(self.name,self.price,self.period)

    # def __str__(self):
    #     return '全栈开发 :'+self.name

py20 = Python('python',25000,'6 months')
print(py20)

打印对象 先走自己的str,如果没有,走父类的,如果除了object之外的所有父类都没有str再回来,找自己的repr,如果自己没有,再找父类的

repr是str的备胎和所有的字符串格式化以及直接打印这个对象相关

str(obj),repr(obj)

流畅的python - repr

print(str('123'))
print(repr('123'))
  • 有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
  • 增强了用户的体验 在程序开发的过程中
  • 如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
  • 如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示

__new__ 构造方法 生产对象的时候用的 - 单例模式

__del__ 析构方法 在删除一个对象之前用的 - 归还操作系统资源

class Foo:
    def __new__(cls, *args, **kwargs):
        print('in new')   # 先执行
        obj = object.__new__(cls)
        print(obj)
        return obj

    def __init__(self):
        print('init',self)    # 后执行

Foo()
  • 实例化一个Foo的对象

    • 先开辟一块儿空间,使用的是Foo这个类内部的__new__

      • 如果我们的Foo类中是没有__new__方法的
      • 调用object类的__new__方法了
class Foo(object):
    def __new__(cls, *args, **kwargs): # cls永远不能使self参数,因为self在之后才被创建
        obj = object.__new__(cls)   # self是在这里被创造出来的
        print('new : ',obj)
        return obj
    def __init__(self):
        print('init',self)

Foo()
  • 在使用self之前,都还有一个生产self的过程

    • 就是在内存中开辟一块属于这个对象的空间,并且在这个空间中存放一个类指针
    • 以上就是__new__做的所有事情

设计模式 - 单例模式

一个类 有且只能有一个实例

class A:pass
a1 = A()
a2 = A()
print(a1)
print(a2)

class A:
    __flag = None
    def __new__(cls, *args, **kwargs):
        if cls.__flag is None:
            cls.__flag = object.__new__(cls)
        return cls.__flag

    def __init__(self,name=None,age=None):
        self.name = name
        if age:
            self.age = age

a1 = A('alex',84)
print(a1)
a2 = A('alex',83)
print(a2)
a3 = A('alex')
print(a3)
print(a1.age)

保证一个类无论 被实例化多少次,只开辟一次空间,始终使用的是同一块内存地址

__del__方法-python解释器

import time
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __del__(self):
        # 只和del obj语法有关系,在执行del obj之前会来执行一下__del__中的内容
        print('执行我啦')

a = A('alex',84)
print(a.name)
print(a.age)
# del a   # 这个变量已经没了
time.sleep(1)
在所有的代码都执行完毕之后,所有的值都会被python解释器回收

python解释器清理内存

  1. 我们主动删除 del obj
  2. python解释器周期性删除
  3. 在程序结束之前 所有的内容都需要清空
import time
class A:
    def __init__(self,path):
        self.f = open(path,'w')
    def __del__(self):
        '''归还一些操作系统的资源的时候使用'''
        '''包括文件\网络\数据库连接'''
        self.f.close()

a = A('userinfo')
time.sleep(1)

__call__

源码里用比较多 Flask web框架

对象()自动触发__call__中的内容

class A:
    def call(self):
        print('in call')
    def __call__(self, *args, **kwargs):
        print('in __call__')

A()()
obj = A()
obj()
obj.call()

with的上下文处理

class File:
    def __enter__(self):
        print('start')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit')

with File():
    print('wahaha')
class myopen:
    def __init__(self,path,mode='r'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        print('start')
        self.f = open(self.path,mode=self.mode)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()
        print('exit')

with myopen('userinfo','a') as f:
    f.write('hello,world')

pickle

import pickle
class MypickleDump:
    def __init__(self,path,mode = 'ab'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        self.f = open(self.path,self.mode)
        return self

    def dump(self,obj):
        pickle.dump(obj,self.f)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

with MypickleDump('pickle_file') as pickle_obj:
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
class MypickelLoad:
   def __init__(self,path,mode='rb'):
       self.path = path
       self.mode = mode

   def __enter__(self):
       self.f = open(self.path,self.mode)
       return self

   def loaditer(self):
       while True:
           try:
               ret = pickle.load(self.f)
               yield ret
           except EOFError:
               break

   def __exit__(self, exc_type, exc_val, exc_tb):
       self.f.close()
with MypickelLoad('pickle_file') as mypic:
    for obj in mypic.loaditer():
        print(obj)

在一个函数的前后添加功能

利用使用 装饰器函数中的内容

with语句 就是和 __enter__,__exit__

import time
class Timer:
    def __enter__(self):
        self.start = time.time()
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(time.time() - self.start)

def func():
    print('wahaha')
    time.sleep(1)
    print('qqxing')

with Timer():
    func()
class MypickleDump:
   def __init__(self,path,mode = 'ab'):
       self.path = path
       self.mode = mode

   def __enter__(self):
       self.f = open(self.path,self.mode)
       return self

   def dump(self,obj):
       pickle.dump(obj,self.f)

   def __exit__(self, exc_type, exc_val, exc_tb):
       self.f.close()

with MypickleDump('pickle_file') as obj:
   obj.dump({1,2,3,4})

with MypickelLoad('pickle_file') as obj:
  for i in  obj.loaditer():
      print(i)

重要内置方法

  • __new__
  • __del__
  • __call__
  • __str__
  • __repr__
  • __enter__
  • __exit__

2019-04-02-day024-内置方法的更多相关文章

  1. js-DOM ~ 04. BOM:浏览器对象模型window. 、定时器、在线用户、祝愿墙、BOM的内置方法内置对象

    multiple. select列表多选 触发事件后调用有参数的函数要先创建一个函数,然后在函数内调用执行函数 Array.from(伪数组):伪数组变为真数组 indexOf():查询字符的索引 a ...

  2. 【python基础】第11回 数据类型内置方法 02

    本章内容概要 列表内置方法 字典内置方法 元组内置方法 集合内置方法 可变类型与不可变类型 本章内容详细 1.列表内置方法 list 列表在调用内置方法之后不会产生新的值 1.1 统计列表中的数据值的 ...

  3. python面向对象的基础语法(dir内置函数、self参数、初始化方法、内置方法和属性)

    面相对象基础语法 目标 dir 内置函数 定义简单的类(只包含方法) 方法中的 self 参数 初始化方法 内置方法和属性 01. dir 内置函数(知道) 在 Python 中 对象几乎是无所不在的 ...

  4. s14 第4天 关于python3.0编码 函数式编程 装饰器 列表生成式 生成器 内置方法

    python3 编码默认为unicode,unicode和utf-8都是默认支持中文的. 如果要python3的编码改为utf-8,则或者在一开始就声明全局使用utf-8 #_*_coding:utf ...

  5. day6 六、元组、字典、集合的基本操作和内置方法

    一.元组 1.定义 # 元组tuple # 记录多个值,当值没有改的需求是,建议用元组更好 # 定义:在()内用逗号分开任意类型的值 # name = (, , 300.5]) # print(nam ...

  6. Python_List对象内置方法详解

    目录 目录 前言 软件环境 列表List 修改列表的元素 插入列表元素 extend 将序列中的元素迭代的附加到list中 insert 在指定的索引号中插入一个元素 删除列表元素 del 删除Lis ...

  7. Python_序列对象内置方法详解_String

    目录 目录 前言 软件环境 序列类型 序列的操作方法 索引调用 切片运算符 扩展切片运算符 序列元素的反转 连接操作符 重复运算符 成员关系符 序列内置方法 len 获取序列对象的长度 zip 混合两 ...

  8. [Python3] 009 字符串:给你们看看我的内置方法 第一弹

    目录 前言 如何查看 python3 中和 str 有关的方法 字符串方法 1. capitalize() 2. casefold() 3. center(width) 4. count(sub[, ...

  9. 数据库(十三):MySQL内置方法

    进击のpython ***** 数据库--MySQL内置方法 目录 数据库--MySQL内置方法 视图 增加 修改 删除 触发器 创建 使用 删除 存储过程 无参 有参 事务 代码实现 视图 视图是一 ...

  10. python黑魔法 -- 内置方法使用

    很多pythonic的代码都会用到内置方法,根据自己的经验,罗列一下自己知道的内置方法. __getitem__ __setitem__ __delitem__ 这三个方法是字典类的内置方法,分别对应 ...

随机推荐

  1. 卸载WPS后怎么WORD的图标还是WPS

    在电脑中选择使用Microsoft Office并将之前安装的WPS Office办公软件卸载了.但是卸载之后发现电脑系统中的Word.Excel等文件无法正常显示图标.在这样的情况下,我们应该如何解 ...

  2. Matlab-8:松弛迭代法(SOR)

    function [x,n,flag]=sor(A,b,eps,M,max1) %sor函数为用松弛迭代法求解线性方程组 %A为线性方程组的系数矩阵 %b为线性方程组的常数向量 %eps为精度要求 % ...

  3. 【PowerDesigner】【1】简单介绍

    正文: 创建表格 File→New Model→(Model types; Physical Data Model; Physical Diagram)Model name:名称:DBMS:数据库类型 ...

  4. [LightOJ 1265] Island of Survival

    Island of Survival You are in a reality show, and the show is way too real that they threw into an i ...

  5. loj 10000 活动安排

    ****这是一个贪心题,把结束时间排个序,然后留出更多的时间给后面的活动. #include<cstdio> #include<cstring> #include<alg ...

  6. [LeetCode] 112. Path Sum ☆(二叉树是否有一条路径的sum等于给定的数)

    Path Sum leetcode java 描述 Given a binary tree and a sum, determine if the tree has a root-to-leaf pa ...

  7. zk 创建瞬时、顺序节点的原理

    命令: create -s -e /worker/lock xx zk 的实现代码在:PrepRequestProcessor.pRequest2Txn 中 //The number of chang ...

  8. Jackson 工具类使用及配置指南

    目录 前言 Jackson使用工具类 Jackson配置属性 Jackson解析JSON数据 Jackson序列化Java对象 前言 Json数据格式这两年发展的很快,其声称相对XML格式有很对好处: ...

  9. 函数----基础,参数传递,返回类型和return语句

    一.函数基础1.形参和实参 实参是形参的初始值.第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推.尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序.编译器能以任意可行的顺序对实 ...

  10. Win10系列:UWP界面布局基础4

    类型转换 前面讲到过,在定义元素时可以通过Attributes特性方式为其设置属性并为属性赋值,在实际开发中所赋予的值可能和属性本身的数据类型不相符,这时XAML解析器就会使用类型转换器(Type C ...