【23.绑定方法与非绑定方法介绍】
再类的内部的定义的函数分为两大类:
1.绑定方法:
绑定到对象的方法:直接用def做的函数属性,类内部定义的函数,如果没有绑定装饰器,就是给对象使用的函数,绑定给谁就给谁来调用
绑定到类的方法
2.非绑定方法:不与类或者对象绑定
# 绑定对象的方法,类去访问自己的函数属性的时候就是一个普通的函数,没有自动调用的方式
# 绑定给谁,就应该谁来调用就会把调用者当做第一个参数自动传入
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def tell(self):
# print('名字是%s' %self.name)
#
# f = Foo('panda')
# print(f.tell)
# -------------------------------------------------------------------
# 绑定到类:在类的内部定义的,被装饰器classmethod修饰的方法
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def tell(self):
# print('名字是%s' %self.name)
#
# @classmethod
# def func(cls):
# print(cls)
#
# Foo.func()
# print(Foo)
# -------------------------------------------------------------------
# 非绑定方法:不与类或者对象绑定,没有自动传值,谁都可以用,就相当于普通函数,一点都没有绑定关系
# 就是类中定义的普通工具
class Foo:
def __init__(self, name):
self.name = name
def tell(self):
print('名字是%s' %self.name)
@staticmethod
def func1(x,y):
return x+y
f = Foo('panda')
print(Foo.func1(1,2))
print(f.func1(1,3))
【24.绑定方法与非绑定方法】
什么场景下使用绑定方法和非绑定方法
import settings
class People:
def __init__(self,name, age, sex):
self.name = name
self.age = age
self.sex = sex
self.id = self.create_id()
def tell_info(self): #绑定到对象的方法
print('Name %s Age %s Sex %s' % (self.name, self.age, self.sex))
@classmethod
def from_conf(cls):
obj = cls(
settings.name,
settings.age,
settings.sex
)
return obj
@staticmethod
def create_id():
import hashlib
import time
m = hashlib.md5(str(time.time()).encode('utf-8'))
return m.hexdigest()
# p1 = People('panda', 18, '男')
# 绑定给对象就由对象来调用,自动将对象本身当做第一个参数传入
# p1.tell_info() #tell_info(p1)
# 新需求:从配置文件里读取信息来实例化对象
# p2 = People(settings.name, settings.age, settings.sex)
# p2.tell_info()
#---------------------------------------------------#
# 绑定给类
# p = People.from_conf()
# p.tell_info()
#---------------------------------------------------#
# 非绑定方法,不与类或者对象绑定,谁都可以调用,没有自动传入值的功能
# p1 = People('panda',20,'male')
# p2 = People('pandaboy',10,'male')
# print(p1.id)
# print(p2.id)
【25.反射】
用户的输入就会变成字符串,input方法就是会转换成字符串的形式
如果通过用户的输入,让用户通过字符串调用类的属性
反射:通过字符串来映射到对象的属性
# class People:
# county = 'China'
# def __init__(self,name, age):
# self.name = name
# self.age = age
# def talk(self):
# print('%s is talking' %self.name)
#
# obj = People('panda', 10)
# print(obj.name)
# obj.talk()
# 用户的输入就会变成字符串,input方法就是会转换成字符串的形式
# 如果通过用户的输入,让用户通过字符串调用类的属性
# 1.hasattr(obj,str)>>判断obj下到底有没有str的参数属性,本质上就是判断字典里有没有str的属性(obj.__dict__(str))>>返回的值是布尔值(True/False)(判断有没有)
# 2.getattr(obj,str,default)>>直接显示str属性的结果,如果没有就报错,default就是直接赋值None(设置)
# 3.setattr(obj,'sex','male')>>等同于obj.sex = male设置对象的值(修改和新增)
# 4.delattr(obj, 'age')>>等同于del obj.age删除对象的值(删除)
# print(getattr(People,'county'))
反射的应用
class Service:
def run(self):
while True:
cmd = input('>>>').strip()
print(cmd)
if hasattr(self,cmd):
func = getattr(self,cmd)
func()
def get(self):
print('get.....')
def put(self):
print('put.....')
obj = Service()
obj.run()
【26.内置方法介绍】
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
对象到底是不是类的实例
class Foo:
pass
obj = Foo()
print(isinstance(obj,Foo))
issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo:
pass
class Bar(Foo):
pass
print(issubclass(Bar,Foo))
Item系列
把对象模拟成python的字典类型的数据实现访问的格式,会把obj模拟成字典的形式
class Foo:
def __init__(self,name):
self.name = name
def __getitem__(self, item):
# print('Get item.....')
# print(item)
return self.__dict__.get(item)
def __setitem__(self, key, value):
# print('Set item.....')
# print(key,value)
self.__dict__[key] = value
def __delitem__(self, key):
self.__dict__.pop(key)
obj = Foo('panda')
#实现obj.name的实现方式,
# 查看属性
print(obj['name'])
#设置赋值方式,设置属性
obj['sex'] = 'male'
print(obj['sex'])
# 删除属性
del obj['name']
print(obj['name'])
__str__方法改变对象的字符串显示,会在打印对象的时候触发,把返回结果(必须是字符串)返回
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '<name %s age %s>' % (self.name, self.age)
obj = People('panda',10)
print(obj)
__del__方法:如果在类的内部调用了__del__方法,这个方法就会绑定给对象,在对象被删除的时候会自动先触发,就会调用垃圾回收机制,即使你不调用,也会在删除对象的时候自动触发__del__方法,
# ___模拟打开文件的操作,在python内部结束了以后,会自动触发__del__的操作,自动回收操作系统资源
class Open:
def __init__(self, filename):
print('open file...')
self.filename = filename
def __del__(self):
print('Finish !')
f = Open('test.txt')
print('At the end')
【27.元类介绍】
面向对象高级难点:元类(metaclass)
储备知识exec--->把字符串里的内容提取出来直接执行
参数1:字符串形式的命令
参数2:全局作用域(字典形式),可以定制一个全局作用域(如果不指定,默认使用globals())
参数3:局部作用域(字典形式),如果不指定默认就使用loacals()
实例化了元类得到了元类的对象,元类的对象实际上就是利用class声明的一个类
g = {
'x':1,
'y':2,
}
l = {}
exec('''
global x,m
x = 10
m = 100
z = 3
''',g, l)
print(g.get('m'))
print(l)
# python中一切皆对象,对象可以怎么使用?
# 1.都可以被引用,x = obj
# 2.都可以当做函数的参数传入
# 3.都可以当做函数的返回值
# 4.都可以当做容器类型的元素,l = [func, time, obj, 1]
# 产生类的类称之为元类,默认所有用class定义的类,他们得元类就是type
# 定义类有两种实现方式
# 1.class关键字的方式
# class Chinese:
# country = 'China'
# def __init__(self,name, age):
# self.name = name
# self.age = age
# def talk(self):
# print('%s is talking' % self.name)
# 2.type元类的产生
# 定义类的三要素
# 1.类的类名
# 2.类的继承,python3中默认继承object
# 3.类必须要有自己的名称空间,里面定义了自己的数据属性和函数属性
class_name = 'Chinese'
class_bases = (object, )
class_body = """
country = 'China'
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print('%s is taking'%self.name)
"""
class_dic = {}
exec(class_body, globals(), class_dic)
Chinese = type(class_name, class_bases, class_dic)
print(class_dic)
【28.自定义元类控制类的创建】
如何自己定制元类来控制class的行为
# # 自定义元类最好指定type,因为你只是重写一部分类的方法,本身更多的类的属性还是从type中来的
#
#
# class Mymeta(type):
# def __init__(self,class_name, class_bases, class_dic):
# if not class_name.istitle():
# raise TypeError('类型错误,类名的首字母必须大写')
# super(Mymeta,self).__init__(class_name,class_bases,class_dic)
#
#
# class Chinese(object, metaclass=Mymeta):
# country = 'China'
#
# def __init__(self,name, age):
# self.name = name
# self.age = age
#
# def talk(self):
# print('%s is talking' % self.name)
# # Chinese = Mymeta(class_name,class_bases,class_dic)
class Foo:
'''
注释
'''
pass
print(Foo.__dict__)
print(Foo.__doc__)
【29.自定义元类控制类的实例化行为】
补充知识点:调用方法__call__
对象实例化以后调用__call__
1.先造一个空对象(object.__new__(self))
2.初始化(self.__init__(obj,*args,**kwargs))
3.返回(return obj)
# class Foo:
# def __call__(self, *args, **kwargs):
# print(self)
# print(args)
# print(kwargs)
#
#
# obj = Foo()
# obj(1,1,3,a=1,b=2)
# 调用对象实际上会触发__call__这个内置方法,不同的值会存成不同的形式保存
# 元类内部也是有一个__call__方法,会在调用Foo时触发执行
# Foo(1,2,x=1) Foo.__call__(Foo,1,2,x=1)
class Mymeta(type):
def __init__(self,class_name, class_bases, class_dic):
if not class_name.istitle():
raise TypeError('类型错误,类名的首字母必须大写')
if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
raise TypeError('必须有注释,且注释不能为空')
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
def __call__(self, *args, **kwargs):
print('>>>>')
class Chinese(object, metaclass=Mymeta):
'''
注释
'''
country = 'China'
def __init__(self,name, age):
self.name = name
self.age = age
def talk(self):
print('%s is talking' % self.name)
# # Chinese = Mymeta(class_name,class_bases,class_dic)
obj = Chinese('panda', 20) # 实际上就是执行Chinese.__call__(Chinese,'panda',20)
【30.自定义元类控制类的实例化行为的应用】
#单例模式:默认参数一样的情况下,就不会生成新的内存空间了,用公用的就行(实际就是一种优化的策略)
#单例模式:默认参数一样的情况下,就不会生成新的内存空间了,用公用的就行(实际就是一种优化的策略)
class MySQL:
__instance = None
def __init__(self):
self.host = '127.0.0.1'
self.port = 3306
@classmethod
def singleton(cls):
if not cls.__instance:
obj = cls()
cls.__instance = obj
return cls.__instance
def find(self):
pass
def update(self):
pass
obj1 = MySQL.singleton()
obj2 = MySQL.singleton()
print(id(obj1))
print(id(obj2))
# #单例模式:默认参数一样的情况下,就不会生成新的内存空间了,用公用的就行(实际就是一种优化的策略)
# class MySQL:
# __instance = None
# def __init__(self):
# self.host = '127.0.0.1'
# self.port = 3306
# @classmethod
# def singleton(cls):
# if not cls.__instance:
# obj = cls()
# cls.__instance = obj
# return cls.__instance
#
# def find(self):
# pass
#
# def update(self):
# pass
#
#
# obj1 = MySQL.singleton()
# obj2 = MySQL.singleton()
#
# print(id(obj1))
# print(id(obj2))
# ---------------------------------------#
# 实现方式二:元类的方式
class Mymeta(type):
def __init__(self,class_name, class_bases, class_dic):
if not class_name.istitle():
raise TypeError('类型错误,类名的首字母必须大写')
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
self.__instance=None
def __call__(self, *args, **kwargs):
if not self.__instance:
obj = object.__new__(self)
self.__init__(obj)
self.__instance = obj
return self.__instance
class Mysql(object,metaclass=Mymeta):
def __init__(self):
self.host = '127.0.0.1'
self.port = 3306
def find(self):
pass
def update(self):
pass
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(id(obj1))
print(id(obj2))
print(id(obj3))
【31.面向对象的软件开发与作业介绍】
【32.什么是异常处理】
【32.try...except...详细方法】
- 路飞学城—Python爬虫实战密训班 第三章
路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...
- 路飞学城—Python爬虫实战密训班 第二章
路飞学城—Python爬虫实战密训班 第二章 一.Selenium基础 Selenium是一个第三方模块,可以完全模拟用户在浏览器上操作(相当于在浏览器上点点点). 1.安装 - pip instal ...
- 路飞学城Python爬虫课第一章笔记
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...
- 路飞学城-Python开发集训-第3章
学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...
- 路飞学城-Python开发集训-第1章
学习体会: 在参加这次集训之前我自己学过一段时间的Python,看过老男孩的免费视频,自我感觉还行,老师写的代码基本上都能看懂,但是实际呢?....今天是集训第一次交作业的时间,突然发现看似简单升级需 ...
- 路飞学城-Python开发集训-第4章
学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ...
- 路飞学城-Python开发集训-第2章
学习心得: 这章对编码的讲解超级赞,现在对于编码终于有一点认知了,但还没有大彻大悟,还需要更加细心的琢磨一下Alex博客和视频,以前真的是被编码折磨死了,因为编码的问题而浪费的时间很多很多,现在终于感 ...
- 路飞学城-Python开发-第二章
''' 数据结构: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, '汽车之家' ...
- 路飞学城-Python开发-第三章
# 数据结构: # goods = [ # {"name": "电脑", "price": 1999}, # {"name&quo ...
- 路飞学城-Python开发-第一章
# 基础需求: # 让用户输入用户名密码 # 认证成功后显示欢迎信息 # 输错三次后退出程序 username = 'pandaboy' password = ' def Login(username ...
随机推荐
- jemeter安装步骤
1.jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi 2.在安装jmeter之前首先要安装jdk1.8以上版本,朋友们,千万不要忘了 jd ...
- Python基础学习_01字符串的拼接(字符串的格式化输出)
# 字符串的拼接 ---字符串的格式化输出 # 字符串的拼接 ---字符串的格式化输出 name = input("name:") age = input("age:&q ...
- UVA1586 - Molar mass(紫书习题3.2)
HJL是一个从不讽刺人的品学兼优的好孩子,她最近沉迷学习化学而不能自拔.然而计算一个分子的相对分子质量使她烦不胜烦,因此她决定请你写一个程序来帮助她计算这种麻烦的事情. 已知: ①C代表的碳元素的相对 ...
- GOF23设计模式之建造者模式
GOF23设计模式之建造者模式 场景: 我们要建造一个复杂的产品.比如:神州飞船,Iphone.这个复杂的产品的创建.有这样的一个问题需要处理: 装配这些子组件是不是有个步骤问题? 实际开发中,我们所 ...
- Ubuntu14.04 Anaconda
我虚拟机Ubuntu14.04上的Python已经存在了两个版本,一个是python 2.7,一个是Python 3.4.想在它上面安装Anaconda,但又有所顾虑.我先想到的是,先卸载Ubuntu ...
- 06006_redis数据存储类型——String
1.概述 (1)字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等: (2)在Redis中 ...
- hdu 2435 dinic算法模板+最小割性质
#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define ...
- RDIFramework.NET V2.9版本号 WinFom部分新增与修正的功能
RDIFramework.NET V2.9版本号 WinFom部分新增与修正的功能 转眼间RDIFramework.NET框架走了快6个年头了,随着一个版本号一个版本号的升级改造,如今已经越来越完美 ...
- java 抽象类和接口的差别
语法层面上: 1)抽象类能够提供成员方法的实现细节.而接口中仅仅能存在public abstract 方法. 2)抽象类中的成员变量能够是各种类型的.而接口中的成员变量仅仅能是public st ...
- 腾讯云 ubuntuservermysql安装和外网訪问
1 腾讯云 购买ubuntu 默认账户是ubuntu(因为winscp 使用ubuntu没有权限写文件) 因为腾讯云主机ubuntu系统默认username为ubuntu,不喜欢每次做什么都要sudo ...