昨日回顾

  • 反射

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

如何反射类

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. python记录_day06

    一.小数据池 注意大前提!!!! 小数据池只针对整数.字符串和bool值,因为这些数据是不可变的,这样数据的共享才安全 小数据池也称为小整数缓存机制或驻留机制,是指在不同代码块创建部分小数据对象(具体 ...

  2. 谈一谈HashMap类

    一.Java中的hashCode()和equals() 1. hashCode()的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode()是用来在散列存储结构中确定对 ...

  3. Win10更改CMD控制台的代码页和字体和字号

    注意:936(简体中文)时,指定Consolas等英文字体将无效,会自动变为“新宋体”. 代码页:若是UTF8(65001)应改为:0000fde9 字号:000e0000 -> 12 cmd_ ...

  4. Linux系统(X64)7 安装Oracle11g完整安装图文教程另附基本操作

    在linux 7.6 安装 oracle 11g    mount 挂载yum源 yum –y sys*  gcc*  lib* sys* ma* un* gli* elf* bin* com*   ...

  5. Hadoop介绍-4.Hadoop中NameNode、DataNode、Secondary、NameNode、JobTracker TaskTracker

    Hadoop是一个能够对大量数据进行分布式处理的软体框架,实现了Google的MapReduce编程模型和框架,能够把应用程式分割成许多的 小的工作单元,并把这些单元放到任何集群节点上执行.在MapR ...

  6. 设计模式之单例模式-C++

    单例模式也称单子模式.单件模式,通过单例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享 对于系统中的某些类来说,只有一个实例很重要,比如一个打印机可以 ...

  7. 使用ES6的reduce函数,根据key去重

    最近很着迷于ES6的函数,让代码变得更优雅.ES6里的reduce函数,平时用的不是特别多,真正用起来发现还是挺好用的. 想要实现的效果为: 原数组: let rawArr = [{id:'123'} ...

  8. shell shell基本概述

    SHELL的概念 SHELL是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序, 用户可以用shell来启动,挂起,停止甚至是编写一些程序. ​ Shell还是 ...

  9. Uva LA 3902 - Network 树形DP 难度: 0

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  10. day18-python的正则表达式

    1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...