昨日回顾

  • 反射

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

如何反射类

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. 『MXNet』第五弹_MXNet.image图像处理

    简单处理API 读取图像: image.imdecode(open('../img/cat1.jpg', 'rb').read()) 图像类型转换: img.astype('float32') 图像增 ...

  2. centos7 keepalived+nginx实现vip漂移高可用

    一.Keepalived 简要介绍 Keepalived 是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前 ...

  3. 关于react16.4——上下文Context

    首先我们来聊一聊(上下文)Context. 上下文(Context) 提供了一种通过组件树传递数据的方法,无需在每个级别手动传递 props 属性. 在典型的 React 应用程序中,数据通过 pro ...

  4. php调用oracle存储

    //todo 调用oracle 存储$config = //数据库配置文件 里面包含 用户密码和host和端口以及dbname $conn = oci_connect($config['usernam ...

  5. jquery 表单提交不用action

    1.今天我做完事去看了一下别人的代码,不用我们很常规的写法.我想让我们来学习一下吧! <form class="form-inline form-mess">//内容在 ...

  6. Leetcode 969. 煎饼排序

    969. 煎饼排序  显示英文描述 我的提交返回竞赛   用户通过次数134 用户尝试次数158 通过次数135 提交次数256 题目难度Medium 给定数组 A,我们可以对其进行煎饼翻转:我们选择 ...

  7. 类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”等一些问题的解决方案

    有些时候我们引用了一些32位的dll,结果就会出现类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”这样的问题,原因是IIS的应用程序池的设置中默认是不启用32位的应用 ...

  8. Oracle用户密码认证方式

    oracle用户有两种认证方式: 操作系统认证(要求该用户属于本地DBA组,然后通过操作系统认证登录oracle,从而启动数据库) 密码文件认证 oracle使用哪种认证方式决定在于两个参数: 1.r ...

  9. [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 ...

  10. 牛客网 PAT 算法历年真题 1002 :数字分类 (20)

    1002 :数字分类 (20) 时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 给定一系列正整数,请按要求对数字 ...