python高级编程——入门语法(一)
元类
在python中一切皆对象,类也是对象,只不过类是一个创建对象的对象,我们可以在类中动态的创建一个类,比如
def func(name):
if name == "Plane":
class Plane(object):
pass
return Plane
else:
class Metrorolite(object):
pass
return Mrtroolite
虽然根据上述代码可以动态创建一个类,但是整个类的代码仍需要我们编写的
type()有两种作用:
1、检查对象类型
class People(object):
def __init__(self, id, name, employees):
self.id = id
self.name = name def func(self):
return if __name__ == "__main__":
id = 1001
name = "abc"
employees = [1,2,3]
people = People(id, name, employees)
# 检查整型
print(type(id)) # <class 'int'>
# 检查字符串型
print(type(name)) # <class 'str'>
# 检查列表型
print(type(employees)) # <class 'list'>
# 检查类的对象型
print(type(people)) # <class '__main__.People'>
# 检查类类型
print(type(People)) # <class 'type'>
# 检查函数型
print(type(people.func)) # <class 'method'> # 如果我们对其结果再次type()得到的结果都是type类型,这就验证了一切解释对象
2、还有一个高大上的作用就是动态的创建类
语法:type(类名, 由父类名称组成的元组(可以为空), 包含属性的字典(名称和值))
返回值是一个类
# 空类
Chinese = type("People", (), {}) # 继承父类,父类以元组的形式表达
Chinses = type("People", (object, ), {}) # 给类一些属性(下述都是类属性)和方法(方法可以自定义,依次是实例方法、类方法、静态方法) def sayHI(self):
print("HI") @classmethod
def sayHello(cls):
print("Hello") @staticmethod
def sayBye():
print("Bye") Chinese = type("People", (object, ), {"id": 1001, "name": "zhangsan", "func1": sayHI, "func2": sayHello, "func3": sayBye}) # Chinese 不是类名,People是类名,Chinese是一个引用变量
元类的定义:
元类就是用来创建类的“东西”
元类是类的类, 是类的模板
元类是用来控制如何创建类的, 正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为
元类的实例化结果是我们用class定义的类,正如类的实例为对象
type是python的一个内建元类, 用来直接控制生成类
python中任何class定义的类其实都是type类实例化的对象
当然了,你也可以创建自己的元类,需要继承 type。
元类的定义和使用:
通过函数返回一个元类:
# 自定义函数
def summary(a, b):
return a+b # 这个函数的作用是修改当前类的属性的值和方法的功能,并且返回一个类
def upper_attr(future_class_name, future_class_parent, future_class_attr): # 可以修改当前类定义的属性的值和方法的功能
newAttr = {}
for name, value in future_class_attr.items():
if name == "bar":
newAttr[name] = "变量值修改了"
if name == "func":
newAttr[name] = summary return type(future_class_name, future_class_parent, newAttr) class Operation(object, metaclass=upper_attr):
bar = "修改之前的值"
func = None if __name__ == "__main__":
print(Operation.bar) # 变量值修改了
print(Operation.func(2, 4)) # 返回值6
通过继承type生成元类(博主也没有看懂,了解即可,用到极少):
class Meta(type):
def __init__(cls, *args, **kwargs):
super().__init__(*args) def __new__(cls, *args, **kwargs):
name, bases, attrs = args
return super().__new__(cls, name, bases, attrs)
class M_Class(metaclass=Meta):
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
def __init__(self):
pass
动态语言
静态语言和动态语言的区别:
静态语言(强类型语言)
静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要 求在使用变量之前必须声明数据类型。
例如:C++、Java、Delphi、C#等。
动态语言(弱类型语言)
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明, 通常变量的类型是被赋值的那个值的类型。
例如:PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
动态语言的特性:
运行的过程中给对象绑定(添加)属性
运行的过程中给类绑定(添加)属性
运行的过程中给类绑定(添加)方法
运行的过程中删除属性、方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age def show():
print("通过类动态增加类方法.")
@classmethod
def show2(cls):
print("通过类动态增加类方法,并且打印id.", cls.id) if __name__ == "__main__":
person = Person("张三", 22) # 运行过程中,给对象添加属性
person.phone = "1847015XXXX"
print(person.phone) # 1847015XXXX # 运行过程中,对象是不能添加方法,否则会报错
# person.func = show
# person.func() # 运行过程中,给类增加属性
Person.id = 10001
print("对象访问类属性", person.id) # 对象访问类属性10001
print("类访问类属性", Person.id) # 类访问类属性10001
# 运行过程中给类增加方法
Person.func = show
Person.func() # 通过类动态增加类方法.
# 运行过程中给类增加类方法
Person.func = show2
Person.func() # 通过类动态增加类方法,并且打印id。10001
__slots__
__slots__作用:
Python允许在定义class的时候,定义一个特殊变量__slots__来限制该 class能添加的属性,当前类就不能定义或者增加__slots__之外的属性了
__slots__注意事项:
__slots__只对类的实例化对象进行限制,不对类进行限制,__slots__变量值是以元组形式表示
__slots__不仅限制类对象的属性,还限制类对象的方法
__slots__仅对当前类起作用,对继承的子类不起作用
在子类中定义__slots__,子类允许定义的属性就是自身的__slots__加上父类的 __slots__
class Person(object):
__slots__ = ("name", "age")
def __init__(self, name, age):
self.name = name
self.age = age if __name__ == "__main__":
person = Person("张三", 22)
# 运行过程中,给对象添加属性实例对象属性只限于name,age
# person.phone = "1847015XXXX"
# print(person.phone) # 运行过程中,给类增加属性,__slots__ 不限制类
Person.id = 10001
print("对象访问类属性", person.id) # 对象访问类属性 10001
print("类访问类属性", Person.id) # 类访问类属性 10001
生成器
概念:Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建生成器的两种方式:
方法1:列表生成式的 [ ] 改成 ( )
numbers = ( i for i in range(100))
通过 next() 函数获得生成器的下一个返回值
没有更多的元素时,抛出 StopIteration 的异常
正确的方法是使用 for 循环,因为生成器也是可迭代对象,并且不需要关心 StopIteration 异
方法2:使用函数创建生成器(实例)
# 斐波那契数列
def fibonacci(num):
a = 0
b = 1
count = 0
temp = 1
while count < num:
yield b
a, b = b, a+b
count += 1 fi = fibonacci(4)
print(next(fi)) #
print(next(fi)) #
print(next(fi)) #
print(next(fi)) # # 没有更多的元素时,抛出 StopIteration 的异常
# 正确的方法是使用 for 循环,因为生成器也是可迭代对象,并且不需要关心StopIteration 异常
print(next(fi)) # error # 所以在使用生成器的时候,需要捕获异常
fi = fibonacci(10)
while True:
try:
print(next(fi))
except StopIteration as e:
print(e)
break
另外生成器也可以传递参数通过send(参数值):
# 斐波那契数列
def fibonacci(num):
a = 0
b = 1
count = 0
temp = 1
while count < num:
temp = yield temp*b
print("temp{}:{}".format(count, temp))
a, b = b, a+b
count += 1
fi = fibonacci(10) print(next(fi))
while True:
try:
print(fi.send(1))
except:
break
迭代器
可迭代对象:
这里先提一下迭代器对象,如果一个对象可以通for循环进行遍历的对象一般都是迭代器对象;python提供了一个Iterable类就是鉴别对象是否是迭代器对象,在鉴别的过程中需要借助isinstance()方法,这个方法是鉴别对象是否属于一个类的对象,这里不能用type()方法,因为type()的作用是鉴别对象是否是类的实例化对象(通过继承的是false)
首先先简单介绍两者检验对象类型的区别:
class A:
def __init__(self):
pass class B(A):
def __init__(self):
super().__init__() if __name__ == "__main__":
a = 123
# 两者检验整型,类似这种,字符串、列表、元组、集合、字典都是一样的结果
print(type(a) == int) # True
print(isinstance(a, int)) # True # 两者主要的区别 直接通过类生成的对象,两者检验的结果是一样的
b = B()
print(type(b) == B) # True
print(isinstance(b, B)) # True
# 若是父类就会有不一样的结果
print(type(b) == A) # False
print(isinstance(b, A)) # True
所以在检验对象时,采用isinstance()比较好,
from collections import Iterable class A:
def __init__(self):
pass class B(A):
def __init__(self):
super().__init__() # 实例生成器函数
def func(self, a):
yield a
a = a + 1
if a == 5:
return if __name__ == "__main__":
b = B()
print(isinstance(b, Iterable)) # False
# 像集合数据类型都是可迭代对象,字符串、列表、元组、集合、字典
b = ""
print(isinstance(b, Iterable)) # True
# 前面提到的生成器,他也是可迭代对象
a = B()
b = a.func(0)
print(isinstance(b, Iterable)) # True
迭代器:
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用 isinstance() 判断一个对象是否是 Iterator 对象:
有两种情况是迭代器:
1、通过生成器函数生成的生成器就是迭代器
2、通iter()函数将可迭代对象转换成迭代器
from collections import Iterator class A:
def __init__(self):
pass class B(A):
def __init__(self):
super().__init__() # 实例生成器函数
def func(self, a):
yield a
a = a + 1
if a == 5:
return if __name__ == "__main__":
b = B()
print(isinstance(b, Iterator)) # False
# 像集合数据类型都是可迭代对象,字符串、列表、元组、集合、字典
b = ""
print(isinstance(b, Iterator)) # True
# 前面提到的生成器,他也是可迭代对象
a = B()
b = a.func(0)
print(isinstance(b, Iterator)) # True # 通过iter()函数将字符串、列表、元组、集合、字典转换成迭代器
b = {}
b = iter(b)
print(isinstance(b, Iterator))
迭代器是可以自定义,只要重写迭代器协议的两个方法
迭代器对象符合迭代器协议,提供两种方法: __iter__() 和 __next__()
__iter__ 返回迭代器对象,并在循环开始时隐式调用。
__next__方法返回下一个值,并在每个循环增量处隐式调用。
__next__在没有更多值返回时引发StopIteration异常,循环结构隐式捕获该 异常以停止迭代。
class Counter:
def __init__(self, low, high):
self.current = low
self.high = high # 生成器的一般固定写法
def __iter__(self):
return self # 在下面函数可以改变迭代器返回的下一个值
def __next__(self):
if self.current > self.high:
raise StopIteration
else:
self.current += 2
return self.current -2
python高级编程——入门语法(一)的更多相关文章
- python高级编程——入门语法(二)
闭包 概念:外函数outer定义一个变量a,又定义一个内函数inner,而这个内函数inner访问了外函数outer的变量a,如果需要改变外函数outer的变量a的值,则需要声明 nonlocal a ...
- python高级编程:有用的设计模式1
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...
- python高级编程技巧
由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr ...
- python高级编程之列表推导式
1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...
- 第十一章:Python高级编程-协程和异步IO
第十一章:Python高级编程-协程和异步IO Python3高级核心技术97讲 笔记 目录 第十一章:Python高级编程-协程和异步IO 11.1 并发.并行.同步.异步.阻塞.非阻塞 11.2 ...
- python高级编程:有用的设计模式3
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...
- python高级编程:有用的设计模式2
# -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...
- python高级编程之选择好名称:完
由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...
- Python游戏编程入门
<Python游戏编程入门>这些文章负责整理在这本书中的知识点.注意事项和课后习题的尝试实现.并且对每一个章节给出的最终实例进行分析和注释. 初识pygame:pie游戏pygame游戏库 ...
随机推荐
- xSS-Reflected
反射性(非持久性XSS),藏在URL中 一般用户访问恶意链接执行 Low <?php header ("X-XSS-Protection: 0"); // Is there ...
- Vs2012帮助文档安装介绍
Vs2012的帮助文档:Microsoft Help Viewer.exe,vs2010对应的是1.0,vs2012对应的是2.0,版本号以此类推 与早期的chm格式的msdn帮助文档不同在于: 1. ...
- mysql的创建数据库表及添加数据
C:\Users\ceshi>mysql -u root -pEnter password: ******Welcome to the MySQL monitor. Commands end w ...
- Virtualbox 修改硬盘的序列号等信息 例
Virtualbox 修改硬盘的序列号等信息 例 http://blog.csdn.net/eidolon8/article/details/42709365 原创 2015年01月14日 14:24 ...
- pycharm初爬虫
今天尝试使用pycharm+beautifulsoup进行爬虫测试.我理解的主要分成了自己写的HTML和百度上的网页两种吧.第一种,读自己写的网页(直接上代码): (主要参考博客:https://bl ...
- Jmeter接口测试,怎么在下一个接口调用上一个接口的数据
常用的两种方式,第二种容易上手1.使用正则提取器 jmeter 如何将上一个请求的结果作为下一个请求的参数——使用正则提取器(http://www.cnblogs.com/0201zcr/p/5089 ...
- wal2json pg扩展centos7构建
使用wal2json可以将pg 变动输出为json 格式,是一个pg 扩展,支持pg9.4+ 目前看到netflix 的dblog 对于pg 的支持就是基于此插件 以下是关于centos 7的构建说明 ...
- <DFS & BFS> 130 127
130. Surrounded Regions BFS: 把所有边界上的O先换成A(标记),再深度遍历周围的点. 最后把O换成X(表示不符合要求),所有的A换回O class Solution { p ...
- ASP.NET开发实战——(二)为什么使用ASP.NET
本文主要内容是通过分析<博客系统>需求,确定使用Web应用的形式来开发,然后介绍了HTML.HTTP的概念,并使用IIS搭建了一个静态的HTML“页面”,从而引出“动态”的ASP.NET. ...
- MySQL实战45讲学习笔记:第十三讲
一.引子 经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变? 那么今天,我就和你聊聊数据库表的空间回收,看看如何解决这个问题. 这里,我们还是针对 ...