day05_雷神_函数进阶
day05
1、迭代器
1.1可迭代对象
str,list,tuple,dict,set,range,文件句柄 等都是可迭代对象
第一种方法:在该对象中,含有__iter__方法的就是可迭代对象,遵循可迭代协议。
print(dir(str))
dir() 打印出str对象的所有方法。
print('__iter__' in dir(list))
返回值: True 说明是可迭代对象
第二种方法: isinstance("123",Iterable)
from collections import Iterable  (需要import Iterable)
a = isinstance("[1,2,3]", Iterable)
print(a)
1.2迭代器
内部含有__iter__ 且含有__next__方法的对象就是迭代器,遵循迭代器协议。
将可迭代对象转换为迭代器(两种方法)
s1 = "abc"
obj_s1 = iter(s1)  #方法一
obj_s1 = s1.__iter__()  #方法二
print(obj_s1)
结果:<str_iterator object at 0x000002370C657390>
迭代器只能通过__next__方法来读取值:
print(obj_s1.__next__())  # a
print(obj_s1.__next__())  # b
print(obj_s1.__next__())  # c
print(obj_s1.__next__())  # 报错:StopIteration
判断是否是迭代器的方法一:
s1 = "asd"
print('__iter__' in dir(s1))  #True
print('__next__' in dir(s1))  #False
obj_s1 = iter(s1)
print('__iter__' in dir(obj_s1))  #True
print('__next__' in dir(obj_s1))  #True
方法二:
s1 = "asd"
obj_s1 = iter(s1)
print(isinstance(s1,Iterator))    #False
print(isinstance(obj_s1,Iterator))    #True
迭代器的好处
节省内存
惰性机制
单向不可逆
1.3生成器
生成器的本质就是迭代器,他是自定义的迭代器(用Python写的)。
- 函数的方式构建一个生成器:
 
示例1:
def func1():
    print(111)
    yield 222
    print(333)
    print(444)
obj_1 = func1()   # g_obj = func1()  # 生成器对象
#  凡是函数中见到yield 他就是生成器
print(obj_1)
print(obj_1.__next__())   # 111, 222  一个next对应一个yield,一一对应
print(obj_1.__next__())   # 报错StopIteration 
示例2:
def cloth():
for i in range(1,5001):
    yield '衣服%s' %i
g_obj = cloth()  #生成器对象
print(g_obj)	#<generator object cloth at 0x0000020ADFBCDE08>
for i in range(1,51):
    print(g_obj.__next__())  # 先来50套
for i in range(1,101):
    print(g_obj.__next__())  # 再加100套,从50到了150套,因为迭代器单向不可逆
send
send和next都是对生成器取值,每一个都要对应一个yield,send 会给上一个yield 发送一个值。
send 不能用在第一次取值。最后一个yield 不能得到值
def func1():
    count = yield 666
    print(count)
    yield 777
    yield 888
g_obj = func1()
print(g_obj.__next__())
# print(g_obj.__next__())
# 666
# None
# 777
print(g_obj.send('taibai'))
# 666
# taibai
# 777
# print(g_obj.send('alex'))  # 相当于给yield 777 整体赋值为"alex",只是没有打印
2、列表推导式(生成器表达式)
遍历模式 l = [ i for i in range(1,11)]
[ (结果需要的变量形式)变量 for 变量 in iterable ]
[变量(加工后的变量) for 变量 in iterable] 遍历模式
l2 = ['python%s期' % i for i in range(1,23)]
print(l2)
[变量(加工后的变量) for 变量 in iterable if 条件] 筛选模式
l2 = [i for i in range(1,31) if i % 3 == 0]
print(l2)
l2_obj = (i for i in range(1,31) if i % 3 == 0)  #将[]换成()就是生成器表达式了。
print(l2_obj)
print(l2_obj.__next__())
print(l2_obj.__next__()) 
li = ["a","c",'houbinglei','alex']
l = [i.upper() for i in li if len(i)>=3 ]
print(l)
区别
# 列表推导式:简单,一行搞定。
# 特别复杂的数据列表推导式无法实现,只能用其他方式实现。
# 列表推导式不能排错。
# 列表推导式与生成器表达式区别
# 1 ,列推直观能看出,但是占内存
# 2,生成器表达式不易看出,但是节省内存。
示例:-
x = {
    'name':'alex',
    'Values':[{'timestamp':1517991992.94,
         'values':100,},
        {'timestamp': 1517992000.94,
        'values': 200,},
        {'timestamp': 1517992014.94,
         'values': 300,},
        {'timestamp': 1517992744.94,
         'values': 350},
        {'timestamp': 1517992800.94,
         'values': 280}
		],}
li = [[i['timestamp'],i['values']] for i in x['Values'] ]
print(li)
关键:从要的数据类型分析出规律。
字典推导式
将一个字典的key和value对调
mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)
3、 内置函数
见过的
'''
len()
print()
input()
range()
list()
tuple()
str()
int()
set()。。。。。
'''
dict()
field = ["id","name","age","phone","job"]
def yie_file():
    with open("yuan_gong",encoding="utf-8") as f:
        for line in f:
            yield line.strip().split()
li = []
for i in yie_file():
    dic = dict(zip(field,i))
    if int(dic['age']) > 25:
        print(dic)
    else:
        li.append(dic)
print(li)
结果:
{'id': '4', 'name': 'houbinglei', 'age': '27', 'phone': '17718351482', 'job': 'IT'}
[{'id': '2', 'name': 'Egon', 'age': '23', 'phone': '13304320533', 'job': 'Tearcher'}, {'id': '3', 'name': 'nezha', 'age': '25', 'phone': '1333235322', 'job': 'IT'}]
1.1. 作用域相关
locals :函数会以字典的类型返回当前位置的全部局部变量。
globals:函数以字典的类型返回全部全局变量。
1.2 其他相关
1.2.1 字符串类型代码的执行,eval,exec
	eval:去除字符串两边的引号,输出里边的结果,并返回最终结果。执行字符串表达式。
print(eval('1 + 2 +3'))
print(eval("{'name':'alex'}"),type(eval("{'name':'alex'}")))
  exec:也是去除两边的引号,但是不返回结果,执行代码,执行文件。
s1 = '''
for i in range(5):
    print(i)
'''
print(exec(s1))
1.2.2 输入输出相关
''' 源码分析
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
    sep:   打印多个值之间的分隔符,默认为空格
    end:   每一次打印的结尾,默认为换行符
    flush: 立即把内容输出到流文件,不作缓存
    """
'''
print(111,222,333,sep='*')  # 111*222*333
print(111,end='')
print(222)  #两行的结果 111222
f = open('log','w',encoding='utf-8')
print('写入文件',file=f,flush=True)
1.2.3 内存相关
hash:获取一个对象(可哈希对象:int,str,Bool,tuple)的哈希值。
id:用于获取对象的内存地址。
print(hash('arg'))
print(id('abc'))  # 2033192957072
1.2.3文件操作相关
open:函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。
1.2.4模块相关__import__
__import__:函数用于动态加载类和函数 。
1.2.5帮助
help:函数用于查看函数或模块用途的详细说明。
1.2.6 调用相关
callable:函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。
name = 'alex'
def func1():
    print(111)
print(callable(name))  False
print(callable(func1))  True
函数名加括号就能用,再面向对象比较有用。
1.2.7查看内置属性
dir:函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
dir()   #  获得当前模块的属性列表
1.3 迭代器生成器相关
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
    try:
        # 获得下一个值:
        x = next(it)
        print(x)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break
iter:函数用来生成迭代器(讲一个可迭代对象,生成迭代器)。
from collections import Iterable
from collections import Iterator
l = [1,2,3]
print(isinstance(l,Iterable))  # True
print(isinstance(l,Iterator))  # False
l1 = iter(l)
print(isinstance(l1,Iterable))  # True
print(isinstance(l1,Iterator))  # True
1.4 基础数据类型相关
1.4.1数字相关(14)
数据类型(4):
bool :用于将给定参数转换为布尔类型,如果没有参数,返回 False。
int:函数用于将一个字符串或数字转换为整型。
float:函数用于将整数和字符串转换成浮点数。
进制转换(3):
bin:将十进制转换成二进制并返回。
oct:将十进制转化成八进制字符串并返回。
hex:将十进制转化成十六进制字符串并返回。
数学运算(7):
abs:函数返回数字的绝对值。
print(abs(-5))  # 5
divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)。
print(divmod(7,2))  # (3, 1)
round:保留浮点数的小数位数,默认保留整数。
print(round(7/3,2))  # 2.33
print(round(7/3))  # 2
pow:求xy次幂。(三个参数为xy的结果对z取余)
print(pow(2,3))  # 两个参数为2**3次幂
print(pow(2,3,3))  # 三个参数为2**3次幂,对3取余。
sum:对可迭代对象进行求和计算(可设置初始值)。
l1 = [i for i in range(100)]
print(sum(l1))
print(sum(l1,100)) # 初始值是100 ,最后算完再加上100
min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。
print(min([1,2,3]))  # 返回此序列最小值
ret = min([1,2,-5,],key=abs)  # 按照绝对值的大小,返回此序列最小值
print(ret)
dic = {'a':3,'b':2,'c':1}
print(min(dic,key=lambda x:dic[x]))
###这里可迭代对象如果是字典,x默认是每个字典的key值;
###如果可迭代对象是s = [[3,2],[7,4],[1,6]]这种,x会默认接收每个元素的第一个值。
max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)
dic = {'a':3,'b':2,'c':1}
print(max(dic,key=lambda x:dic[x]))
# x为dic的key,lambda的返回值(即dic的值进行比较)返回最大的值对应的键,x默认接收字典的key。
1.4.2和数据结构相关(24)
列表和元祖(2)
list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素)。
tuple:将一个可迭代对象转化成元祖(如果是字典,默认将key作为元祖的元素)。
l = list((1,2,3))
print(l)
l = list({1,2,3})
print(l)
l = list({'k1':1,'k2':2})
print(l)
相关内置函数(2)
reversed:将一个序列翻转,并返回此翻转序列的迭代器。
l3 = [2, 3, 9, 8, 7, 4]
l3.reverse()
print(l3)
l_obj = reversed(l3)
print(l_obj)   #<list_reverseiterator object at 0x0000025DDEB47908>
for i in l_obj:
    print(i)
print(sum(l_obj))  # 33  sum直接求和迭代器。
print(sum(l3))		# 33  sum 本身就可以求和可迭代对象。
slice:构造一个切片对象,用于列表的切片。
字符串相关(9)
str:将数据转化成字符串。
format:与具体数据相关,用于计算各种小数,精算等。
print(format('test', '<30'))    左对齐
print(format('test', '>20'))	右对齐
print(format('test', '^20'))	剧中
bytes:用于不同编码之间的转化。相当于encode
s1 = "abc"
print(bytes(s1,encoding="utf-8"))
print(s1.encode("utf-8"))
两种方法将str转换为bytes数据类型;解码只能用decode
ord:输入字符找该字符编码的位置 unicode
print(ord('a'))  # 97
print(ord('中'))   #20013
chr:输入位置数字找出其对应的字符
print(chr(97))
print(chr(20013))
ascii:是ascii码中的返回该值,不是就返回/u...
print(ascii('a'))
print(ascii('中'))
repr:返回一个对象的string形式(原形毕露)。
print(repr('{"name":"alex"}'),type(repr('{"name":"alex"}')))  #'{"name":"alex"}' <class 'str'>
print('{"name":"alex"}')
print('python%s期' % '22')  # python22期
print('python%r期' % '22')   # python'22'期
数据集合(3)
dict:创建一个字典。
set:创建一个集合。
frozenset:返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。
*** sorted:对所有可迭代的对象进行排序操作。返回列表。
L = [('a', 1), ('c', 3), ('d', 4),('b', 2), ]
sorted(L, key=lambda x:x[1])               # 利用key
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
x:自动获取可迭代对象的每一个值,并默认按照每个元素的第一个值排序。
字典默认是对Key排序。
dic = {"c":1,"a":3,"b":9}
print(sorted(dic))   #['a', 'b', 'c']
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=lambda s: s[2])            # 按年龄排序
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
sorted(students, key=lambda s: s[2], reverse=True)    # 按降序
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
*** enumerate:枚举,返回一个枚举对象。
dic = {"c":1,"a":3,"b":9}
for i in enumerate(dic):
    print(i)
结果:
(0, 'c')
(1, 'a')
(2, 'b')
for index,key in enumerate(dic):
    print("序号{}的值是{}".format(index,key))
结果:
序号0的值是c
序号1的值是a
序号2的值是b
all:可迭代对象中,全都是True才是True
any:可迭代对象中,有一个True 就是True
l1 = [1, 'alex', 3]
l2 = [0, '', False,(), 1]
print(all(l1))
print(any(l2))
***zip 拉链方法,函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,并没有返回列表,需要用for循环读取这个迭代器。
l1 = [1,2,3,]
l2 = ['a','b','c',5]
l3 = ('*','**',(1,2,3),666,777)
for i in zip(l1, l2, l3):
    print(i)
结果:
(1, 'a', '*')
(2, 'b', '**')
(3, 'c', (1, 2, 3))
***map:会根据提供的函数对指定序列做映射。返回的是迭代器,类似于列表推导式的遍历模式。
>>>def square(x) :            # 计算平方数
...     return x ** 2
...
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
<map object at 0x00000268A1747908>
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
filter:过滤·。
类似于[i for i in range(1,8) if i % 2 == 0 ]
def func(x):return x%2 == 0
ret = filter(func,[1,2,3,4,5,6,7])
print(ret)   #<filter object at 0x0000018EE48679B0>
for i in ret:
    print(i)
	portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}]
ret = filter(lambda x:x['price'] > 100, portfolio )
print(ret)  # <filter object at 0x0000021B7F357E48>
for i in ret:
    print(i)
min,max,sorted,map,filter
返回结果:
filter: ret = filter(lambda x:x['price'] > 100, portfolio )
			print(ret)
			<filter object at 0x0000021B7F357E48>  返回迭代器
sorted: students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
			sorted(students, key=lambda s: s[2])            # 按年龄排序
			[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  返回列表
zip: ret = zip(l_new,l2,tu)
			print(ret) <zip object at 0x00000292D35BE5C8> 返回迭代器
		for i in a:
			print(i)
			(3, 'oldboy', '**')   返回元祖
map:  ret = map(lambda x:x['shares'] * x['price'], portfolio)  # 字典的两个值相乘。
		print(ret)  <map object at 0x000002CFC04E7EB8>  返回迭代器
		li = []
		for i in ret:
		    li.append(i)
		print(li)
list: l=[{'name':'alex'},{'name':'y'}]
		ret = map(lambda x:x['name']+'SB', l)  ret是迭代器。
		print(list(ret))  	list()将可迭代对象转换为列表,同样可以直接转换迭代器。
		结果: ['alexSB', 'ySB']
4 匿名函数
def func(x,y): return x + y
	print(func(3,4))
func1 = lambda x,y: x + y
	print(func1(3,4))
#def func1(x): return x**2
res = map(lambda x: x**2,[1,5,7,4,8])
for i in res:
    print(i)
5.函数的有用信息
from functools import wraps
def logger(f):
    @wraps(f)
    def inner(*args, **kwargs):
        """
        :param args: 函数名,密码
        :param kwargs: 备用
        :return:  True
        """
        ret = f(*args, **kwargs)
        return ret
    return inner
@logger
def login(username,password):
    """
    此函数是完成登录功能的函数,需要用户名,和密码两个参数,返回True 登陆成功
    :return:  True
    """
    print(666)
    return True
login(1,2)  #inner()
# # login('alex', 123)
print(login.__doc__)
print(login.__name__)
遇到装饰器的时候,要还是打印原函数的有用信息,需要from functools import wraps。并且正在inner函数上添加@wraps(f)。
6. 装饰器的升级
带参数的装饰器
1,将@ 与函数分开@ timmerout(flag) 返回了timmer
2,将@timmer结合
def timmerout(flag1):  # flag1 =flag
    def timmer(f):
        def inner(*args,**kwargs):
            if flag1:
				print(flag1)
                start_time = time.time()
                ret = f(*args,**kwargs)
                end_time = time.time()
                print('此函数的执行效率%s' % (end_time - start_time))
                return ret
            else:
                ret = f(*args, **kwargs)
                return ret
        return inner
    return timmer
@timmerout('京东')  # 1,将@ 与函数分开@     timmerout(flag)  返回了timmer 2,将@timmer结合。
def JDshop():
    time.sleep(0.3)
    print('非常复杂......')
    return 666
@timmerout('京东')
def JD():
    time.sleep(0.3)
    print('非常复杂......')
    return 666
@timmerout('淘宝')
def taobao():
    time.sleep(0.1)
    print('非常复杂......')
    return 666
@timmerout('淘宝')
def taobaoshop():
    time.sleep(0.1)
    print('非常复杂......')
    return 666
taobaoshop()
结果 :
淘宝
非常复杂......
此函数的执行效率0.10024571418762207
多个装饰器装饰一个函数
@wrapper2  # f = warpper2(f)  里面的f是inner1 外面的f是inner2
@wrapper1  # f = warpper1(f)  里面的f函数名 外面的f 是inner1
def f():
    print('in f')  # 3
f()  # inner2()
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func												
											day05_雷神_函数进阶的更多相关文章
- day07_雷神_面向对象进阶
		
day07 1.接口类(抽象类) 接口类和抽象类是一种规范,写代码时的规范. 两个思想: 一个是统一接口,一个是定义规则. 最终版本:接口类,抽象类,是一种规范,写代码时的规范 强制性的规定. fro ...
 - Python练习_函数进阶_day10
		
1. 1.作业 1,写函数,接收n个数字,求这些参数数字的和.(动态传参) 2,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么? a=10 b=20 def test5(a,b): p ...
 - day04_雷神_函数
		
#day04 1.函数 1.1函数传参 函数定义的时候是形参:函数执行的时候是实参 实参: 位置参数.关键字参数.混合参数 位置参数:位置一一对应 关键字参数: 可以位置不对应 混合参数:关键字参数要 ...
 - 5 Python3 函数进阶&迭代器与生成器
		
1.函数进阶 1.1.名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的 ...
 - Oracle学习总结_day03_day04_条件查询_排序_函数_子查询
		
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...
 - 深入理解javascript函数进阶系列第一篇——高阶函数
		
前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...
 - 【python 3】 函数 进阶
		
函数进阶 1.函数命名空间和作用域 命名空间一共分为三种: 全局命名空间 局部命名空间 内置命名空间 *内置命名空间中存放了python解释器为我们提供的名字:input , print , str ...
 - day11.1函数进阶 列表集合 字典中的函数变量,函数作为形参
		
函数进阶 1.函数作为变量 a=123 name="gao" nums=[1,2,3] data=nums#指向同一个内存地址 #查看内存地址篇章 def func(): prin ...
 - python基础  (初识函数&函数进阶)
		
函数基础部分 .什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...
 
随机推荐
- BZOJ1227或洛谷2154 [SDOI2009]虔诚的墓主人
			
BZOJ原题链接 洛谷原题链接 又是扫描线,题解可看大佬的博客(太懒了不想打) #include<cstdio> #include<algorithm> using names ...
 - UI设计教程:关于版式设计
			
版式设计是视觉传达的重要手段之一,版式设计,即把有限的视觉元素在版面页进行有效的视觉组合,最优化地传达信息的同时,去影响受众,使受众产生视觉上的美感. 版式设计基本流程 在进行版式设计时,设计作品的 ...
 - tmp下莫名其妙生成root权限的缓存文件
			
现象: 原因:跟ngnix.conf有关,跟tmp的owner有关
 - 【SpringAop】【统一日志处理】注解方式理解以及使用
			
[注意:本次代码的demo会存在百度网盘,由于公司的保密,禁止上传,所以仅本人可见] 目前公司在做数据资产项目,数据质量部分使用到了springaop做统一日志处理,以前对这块有了解,有点模糊不清,今 ...
 - 设计师别浪费时间啦,快来试试这款Sketch标注插件吧
			
随着移动互联网的快速发展,用户的需求也在不断地增大,这对产品经理还有设计师的考验是越来越大.市场环境的变化让我们深信为快不破,但是一个产品的产出需要各个环节的紧密配合,但往往在产品输出过程中,由于分工 ...
 - 获取JavaScript异步函数的返回值
			
今天研究一个小问题: 怎么拿到JavaScript异步函数的返回值? 1.错误尝试 当年未入行时,我的最初尝试: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <s ...
 - 将hibernate框架融入到spring框架中
			
第一步:首先创建表: create table user( id int(2) primary key,name varchar(20),password varchar(20)); 第二步:建立d ...
 - PSP(3.30——4.5)以及周记录
			
1.PSP 3.30 12:00 13:00 10 50 Account前端 A Y min 13:00 13:20 0 20 站立会议 A Y min 15:15 17:00 20 85 Accou ...
 - idea下使用lombok
			
转载 https://blog.csdn.net/u013177446/article/details/53943365 (1)pom引入依赖 <dependency> <group ...
 - 【轻松前端之旅】元素,标记,属性,<html>标签
			
HTML文档是由HTML元素定义的. HTML元素(element)指的是从开始标签(start tag)到结束标签(end tag)的所有代码. 有些元素会使用简写记法,如<img src=' ...