Day 8:16 个类型函数和 10 个类对象相关的内置函数大盘点
你好,我是悦创。
今天,学习 Python 与类型创建、管理自定义类相关的内置函数。
在讲解下面 26 个内置函数前,介绍一个非常重要的知识点:函数作用域问题。
在学习 Python 函数时,我们经常会遇到变量作用域的问题,有全局变量,局部变量等,Python 查找变量的顺序遵守 LEGB 规则,即遇到某个变量时:
- 优先从它所属的函数(local)内查找;
- 若找不到,并且它位于一个内嵌函数中,就再到它的父函数(enclosing)中查找;
- 如果还是找不到,再去全局作用域(global)查找;
- 再找不到,最后去内置作用域(
build-in
)查找。 - 若还是找不到,报错。
如下例子,变量 c 在局部作用域(local)被发现;变量 b 在 parent 函数和 son 函数间(enclosing)被发现;变量 a 在全局作用域(global)被发现;min 函数属于 Python 中内置函数,所以在搜寻完 LEG 三个区域后,最终在 build-in
域被找到。
a = 10
def parent():
b = 20
def son():
c = 30 # c: local
print(b + c) # b: enclosing
print(a + b + c ) # a: global
print(min(a, b, c)) # min : built-in
son()
In [72]: parent()
50
60
10
如下变量 d,在 LEGB 四个域都被搜寻一遍后,还是未找到,就会抛出 d 没有被发现的异常。
a = 10
def parent():
b = 20
def son():
c = 30 # c: local
print(b + c) # b: enclosing
print(a + b + c ) # a: global
print(min(a, b, c)) # min : built-in
print(d) # 在 LEGB 四个域都未找到后,报错!
son()
parent()
# NameError: name 'd' is not defined
1. 类型函数
1.1 bool([x])
测试一个对象是 True,还是 False。
In [38]: bool([0, 0, 0])
Out[38]: True
In [39]: bool([])
Out[39]: False
In [40]: bool([1, 0, 1])
Out[40]: True
1.2 bytes([source[, encoding[, errors]]])
将一个字符串转换成字节类型:
In [44]: s = "apple"
In [45]: bytes(s, encoding='utf-8')
Out[45]: b'apple'
1.3 str(object='')
将字符类型、数值类型等转换为字符串类型:
In [1]: i = 100
In [2]: str(i)
Out[2]: '100'
1.4 chr(i, /)
查看十进制整数对应的 ASCII 字符:
In [54]: chr(65)
Out[54]: 'A'
1.5 ord(c, /)
查看某个 ASCII 字符对应的十进制数:
In [60]: ord('A')
Out[60]: 65
1.6 dict()
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
创建数据字典:
In [92]: dict()
Out[92]: {}
In [93]: dict(a='a',b='b')
Out[93]: {'a': 'a', 'b': 'b'}
In [94]: dict(zip(['a','b'],[1,2]))
Out[94]: {'a': 1, 'b': 2}
In [95]: dict([('a',1),('b',2)])
Out[95]: {'a': 1, 'b': 2}
1.7 object()
返回一个根对象,它是所有类的基类。
In [137]: o = object()
In [138]: type(o)
Out[138]: object
使用魔法函数 __dir__
,查看 object 对象上的所有方法:
In [2]: o.__dir__()
Out[2]:
['__repr__',
'__hash__',
'__str__',
'__getattribute__',
'__setattr__',
'__delattr__',
'__lt__',
'__le__',
'__eq__',
'__ne__',
'__gt__',
'__ge__',
'__init__',
'__new__',
'__reduce_ex__',
'__reduce__',
'__subclasshook__',
'__init_subclass__',
'__format__',
'__sizeof__',
'__dir__',
'__class__',
'__doc__']
1.8int(x)
int(x, base =10)
,x 可能为字符串或数值,将 x 转换为一个整数s
In [16]: int('12')
Out[16]: 12
In [120]: int('12', 16)
Out[120]: 18
若 x 不能转化为整数,则抛出 ValueError 异常:
In [3]: int('ws')
ValueError: invalid literal for int() with base 10: 'ws'
1.9 float(x=0, /)
将一个字符串或整数转换为浮点数:
In [103]: float('30')
Out[103]: 30.0
1.10 frozenset([iterable])
创建一个不可修改的冻结集合,一旦创建不允许增删元素。
In [30]: s = frozenset([1, 1, 3, 2, 3])
In [31]: s
Out[31]: frozenset({1, 2, 3})
但是,普通集合 set 创建后,仍然可以增删元素。
创建一个普通集合 s:
In [26]: s= {1, 2, 3}
创建 s 后,仍然能通过 add 方法,再插入元素:
In [28]: s.add(4)
In [29]: s
Out[29]: {1, 2, 3, 4}
普通集合也能删除元素,使用 pop 方法移除集合的第一个元素:
In [35]: s = {1, 2, 3}
In [36]: s.pop()
Out[36]: 1
In [37]: s
Out[37]: {2, 3}
1.11list([iterable])
返回可变序列类型:列表。如下,集合类型转列表:
In [38]: s = {1, 2, 3}
In [39]: list(s)
Out[39]: [1, 2, 3]
list 函数还常用在,可迭代类型(Iterable)转化为列表。
如下,使用 map 函数,转化列表内每一个整形元素为字符串型。
m 是可迭代类型,经过 list 转化后,看到列表 l。
In [43]: m = map(lambda i:str(i), [186,1243,3201])
Out[43]: l = list(m)
相似的一个例子:
In [85]: list(map(lambda x: x%2==1, [1, 3, 2, 4, 1]))
Out[85]: [True, True, False, False, True]
1.12 range(stop);range(start, stop[,step])
Python 提供两个内置的 range 函数,生成不可变序列:
In [153]: range(11) # 只有一个参数,默认初始值为 0,步长为 1
Out[153]: range(0, 11)
In [154]: range(0, 11, 1) #三个参数都提供,分别是开始、终止、步长值
Out[154]: range(0, 11)
1.13 set([iterable])
返回一个集合对象,并允许创建后再增加、删除元素。
集合的一大优点,容器里不允许有重复元素,因此可对列表内的元素去重。
In [159]: a = [1, 4, 2, 3, 1]
In [160]: set(a)
Out[160]: {1, 2, 3, 4}
1.14 slice(stop);slice(start, stop[, step])
返回一个由 range(start, stop, step)
所指定索引集的 slice 对象:
In [170]: a = [1, 4, 2, 3, 1]
In [171]: a[slice(0, 5, 2)] # 等价于 a[0: 5: 2]
Out[171]: [1, 2, 1]
1.15 tuple([iterable])
创建一个不可修改的元组对象:
In [59]: t = tuple(range(10))
In [60]: t
Out[60]: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
1.16 type(object);type(name, bases, dict)
这是两个查看对象的类型的函数。
自定义类 Student,创建实例 xiaoming:
In [61]: class Student:
...: pass
In [63]: xiaoming = Student()
调用 type 查看 xiaoming 的类型:
In [64]: type(xiaoming)
Out[64]: __main__.Student
type 函数是非常实用的,阅读他人代码时,若函数参数类型没有显示给出,就会用到 type 函数。
In [187]: type((1, 2, 3))
Out[187]: tuple
1.17 zip(*iterables)
创建一个迭代器,聚合每个可迭代对象的元素。
参数前带 *
,意味着是可变序列参数,可传入 1 个,2 个或多个参数。
传入 1 个参数:
In [68]: for i in zip([1, 2]):
...: print(i)
...:
(1,)
(2,)
传入 2 个参数:
In [191]: a = range(5)
In [192]: b = list('abcde')
In [193]: b
Out[193]: ['a', 'b', 'c', 'd', 'e']
In [194]: [str(y) + str(x) for x, y in zip(a, b)]
Out[194]: ['a0', 'b1', 'c2', 'd3', 'e4']
2. 类对象及属性
2.1 classmethod
classmethod 修饰符对应的函数不需要实例化,不需要 self 参数。
第一个参数需要是表示自身类的 cls 参数,能调用类的属性、方法、实例等。
In [77]: class Student():
...: def __init__(self,id=None,name=None):
...: self.id = id
...: self.name = name
...:
...: def instance_method(self):
...: print('这是实例方法')
...: return self
...:
...: @classmethod
...: def __annotations__(cls):
...: return "学生类"
...:
...: @classmethod
...: def print_type_name(cls):
...: print('这是类上的方法,类名为 %s,注解为 %s'%(cls.__name__, cls.__annotations__()))
In [78]: Student().print_type_name()
...: Student().instance_method()
...:
这是类上的方法,类名为 Student,注解为学生类
这是实例方法
Out[78]: <__main__.Student at 0x154ef861308>
2.2 delattr(object, name)
删除对象的属性,在不需要某个或某些属性时,这个方法就会很有用。
In [79]: class Student():
...: def __init__(self,id=None,name=None):
...: self.id = id
...: self.name = name
In [80]: xiaoming = Student(1,'xiaoming')
In [81]: delattr(xiaoming,'id')
In [82]: xiaoming.id
AttributeError: 'Student' object has no attribute 'id'
In [88]: hasattr(xiaoming,'id') # xiaoming 上没有 id 属性
Out[88]: False
2.3 dir([object])
不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时返回参数的属性、方法列表。
In [96]: dir(xiaoming)
Out[96]:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'name']
2.4 getattr(object, name[, default])
获取对象的属性:
In [79]: class Student():
...: def __init__(self, id=None, name=None):
...: self.id = id
...: self.name = name
In [106]: getattr(xiaoming,'name')
Out[106]: 'xiaoming'
2.5 hasattr(object, name)
In [79]: class Student():
...: def __init__(self, id=None, name=None):
...: self.id = id
...: self.name = name
In [110]: hasattr(xiaoming, 'name')
Out[110]: True
In [81]: delattr(xiaoming, 'id')
In [111]: hasattr(xiaoming, 'id')
Out[111]: False
2.6 isinstance(object, classinfo)
判断 object 是否为类 classinfo 的实例,若是,返回 true。
In [79]: class Student():
...: def __init__(self, id=None, name=None):
...: self.id = id
...: self.name = name
In [21]: xiaoming = Student('001','xiaoming')
In [22]: isinstance(xiaoming,Student)
Out[22]: True
序列类型的基类为 Iterable,所以返回 True:
In [85]: from collections.abc import Iterable
In [84]: isinstance([1, 2, 3],Iterable)
Out[84]: True
2.7 issubclass(class, classinfo)
如果 class 是 classinfo 类的子类,返回 True:
In [27]: class undergraduate(Student):
...: def studyClass(self):
...: pass
...: def attendActivity(self):
...: pass
...:
In [28]: issubclass(undergraduate, Student)
Out[28]: True
In [29]: issubclass(object, Student)
Out[29]: False
In [30]: issubclass(Student, object)
Out[30]: True
classinfo 取值也可能为元组,若 class 是元组内某个元素类型的子类,也会返回 True:
In [26]: issubclass(int, (int, float) )
Out[26]: True
2.8 property(fget=None, fset=None, fdel=None, doc=None)
返回 property 属性。不适用装饰器,定义类上的属性:
class Student:
def __init__(self):
self._name = None
def get_name(self):
return self._name
def set_name(self, val):
self._name = val
def del_name(self):
del self._name
# 显示调用 property 函数
name = property(get_name, set_name, del_name, "name property")
显示的调用 property 函数定义类上的属性:
In [94]: xiaoming = Student()
...: xiaoming.name = 'xiaoming'
In [95]: xiaoming.name
Out[95]: 'xiaoming'
使用 Python 装饰器 @property
,同样能实现对类上属性的定义 ,并且更简洁:
class Student:
def __init__(self):
self._name = None
@property
def name(self):
return self._name
@name.setter
def name(self, val):
self._name = val
@name.deleter
def name(self):
del self._name
In [98]: xiaoming = Student()
In [99]: xiaoming.name = 'xiaoming'
In [101]: xiaoming.name
Out[101]: 'xiaoming'
2.9 super([type[, object-or-type]])
返回一个代理对象,它会将方法调用委托给 type 的父类或兄弟类。
如下,子类的 add 方法,一部分直接调用父类 add,再有一部分个性的行为:打印结果。
In [1]: class Parent():
...: def __init__(self, x):
...: self.v = x
...:
...: def add(self,x):
...: return self.v + x
In [2]: class Son(Parent):
...: def add(self, y):
...: r = super().add(y) #直接调用父类的add方法
...: print(r) #子类的add与父类相比,能实现对结果的打印功能
...:
In [3]: Son(1).add(2)
3
2.10 callable(object)
判断对象是否可被调用,能被调用的对象就是一个 callable 对象,比如函数 str、int 等都是可被调用的。
In [1]: callable(str)
Out[1]: True
In [2]: callable(int)
Out[2]: True
如下,xiaoming 实例不可被调用:
In [79]: class Student():
...: def __init__(self, id=None, name=None):
...: self.id = id
...: self.name = name
In [21]: xiaoming = Student('001', 'xiaoming')
In [4]: callable(xiaoming)
Out[4]: False
如果 xiaoming 能被调用:
xiaoming()
必须要重写 Student 类上 __call__
方法:
In [1]: class Student():
...: def __init__(self, id, name):
...: self.id = id
...: self.name = name
...: def __call__(self):
...: print('I can be called')
...: print(f'my name is {self.name}')
In [2]: t = Student('001', 'xiaoming')
In [3]: t()
I can be called
my name is xiaoming
3. 小结
今天学习 26 个内置函数:
- 16 个 Python 内置的与类型相关的函数
- 10 个与自定义类属性、方法管理相关
欢迎关注我公众号:AI悦创,有更多更好玩的等你发现!
公众号:AI悦创【二维码】
AI悦创·编程一对一
AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh
C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh
方法一:QQ
方法二:微信:Jiabcdefh
- 0
- 0
- 0
- 0
- 0
- 0