ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python2部分基础知识

2020-06-02 15:03:09  阅读:290  来源: 互联网

标签:__ shoplist name 对象 self 基础知识 print 部分 python2


1.数据结构 Python中有三种内建的数据结构——列表、元组和字典 (30).列表 list是处理一组有序的数据结构,即你可以在一个列表中存储一个 序列 的数据。并且里面的值是能够被改变的 列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表。一旦你创建了一个列表,你可以添加、删除或是搜索列表中的项目。 [1,2,3,4]  逗号分割 由于你可以增加或删除项目,我们说列表是 可变的 数据类型,即这种类型是可以被改变的。   代码示例 shoplist = ['apple', 'mango', 'carrot', 'banana'] print 'I have', len(shoplist),'items to purchase.' print 'These items are:', # Notice the comma at end of the line for item in shoplist: print item,                #python2         print (item,end="")    #python3   print '\nI also have to buy rice.' shoplist.append('rice') print 'My shopping list is now', shoplist   print 'I will sort my list now' shoplist.sort() print 'Sorted shopping list is', shoplist   print 'The first item I will buy is', shoplist[0] olditem = shoplist[0] del shoplist[0] print 'I bought the', olditem print 'My shopping list is now', shoplist   print语句的结尾使用了一个 逗号(py2)py3是,end=   来消除每个print语句自动打印的换行符   sort方法来对列表排序。需要理解的是,这个方法影响列表本身,而不是返回一个修改后的列表 del语句为我们从列表中删除它。我们指明我们想要删除列表中的第一个元素,因此使用del shoplist[0] 可以通过help(list)获得关于list完整的信息 (31).元组 元组和列表十分类似,只不过元组和字符串一样是 不可变的 即你不能修改元组。元组通过圆括号中用逗号分割的项目定义。元组通常用在使语句或用户定义的函数能够安全地采用一组值的时候,即被使用的元组的值不会改变。 代码示例 zoo = ('wolf', 'elephant', 'penguin') print 'Number of animals in the zoo is', len(zoo) new_zoo = ('monkey', 'dolphin', zoo) print 'Number of animals in the new zoo is', len(new_zoo) print 'All animals in new zoo are', new_zoo print 'Animals brought from old zoo are', new_zoo[2] print 'Last animal brought from old zoo is', new_zoo[2][2]   元组是不能改变的 zoo.__add__('tiger') 元组结合打印语句 age = 22 name = 'Swaroop' print '%s is %d years old' % (name, age) print 'Why is %s playing with that python?' % name   %s表示字符串或%d表示整数。元组必须按照相同的顺序来对应 (32).字典与集合 字典类似于java的map 使用不可变的对象(比如字符串)来作为字典的键,但是你可以把不可变或可变的对象作为字典的值。基本说来就是,你应该只使用简单的对象作为键。键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }。注意它们的键/值对用冒号分割,而每组KV使用逗号分割,所有这些都包括在花括号中。记住字典中的键/值对是没有顺序的。如果你想要一个特定的顺序,那么你应该在使用前自己对它们排序。 字典是dict类的实例/对象。   代码示例 ab = { 'Swaroop' : 'swaroopch@byteofpython.info','Larry' : 'larry@wall.org','Matsumoto' : 'matz@ruby-lang.org','Spammer' : 'spammer@hotmail.com'}   print "Swaroop's address is %s" % ab['Swaroop'] # Adding a key/value pair ab['Guido'] = 'guido@python.org' # Deleting a key/value pair del ab['Spammer'] print '\nThere are %d contacts in the address-book\n' % len(ab) #循环 for name, address in ab.items(): print 'Contact %s at %s' % (name, address) #判断是否存在 if 'Guido' in ab: # OR ab.has_key('Guido') print "\nGuido's address is %s" % ab['Guido'] 修改或者添加
list = {1:'a',2:'b'}
list[3]=('c')
list[3]=('d')
del语句来删除键/值对。我们只需要指明字典和用索引操作符指明要删除的键,然后把它们传递给del语句 使用字典的items方法,来使用字典中的每个键/值对。这会返回一个元组的列表,其中每个元组都包含一对项目——键与对应的值,然后分别赋给for..in循环中的变量name和address 使用in操作符来检验一个键/值对是否存在,或者使用dict类的has_key方法 集合 set set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
要创建一个set,需要提供一个list作为输入集合: s = set([1, 2, 3]) 注意,传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。。 重复元素在set中自动被过滤: s = set([1, 1, 2, 2, 3, 3]) 通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果: s.add(4) {1, 2, 3, 4} s.add(4) 通过remove(key)方法可以删除元素: s.remove(4) set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作: s1 = set([1, 2, 3]) s2 = set([2, 3, 4]) s1 & s2 {2, 3} s1 | s2 {1, 2, 3, 4} set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。 放可变的对象没有报错,因为可变的对象不会改变 
(33).列表、元组和字符串都可以看成一序列数据,都可以通过索引操作符让我们可以从序列中抓取一个特定项目或取其中一部分数据,也就是序列数据的切片 代码示例 shoplist = ['apple', 'mango', 'carrot', 'banana'] # Indexing or 'Subscription' operation print 'Item 0 is', shoplist[0] print 'Item 1 is', shoplist[1] print 'Item 2 is', shoplist[2] print 'Item 3 is', shoplist[3] print 'Item -1 is', shoplist[-1] print 'Item -2 is', shoplist[-2] # Slicing on a list print 'Item 1 to 3 is', shoplist[1:3] print 'Item 2 to end is', shoplist[2:] print 'Item 1 to -1 is', shoplist[1:-1] print 'Item start to end is', shoplist[:] # Slicing on a string name = 'swaroop' print 'characters 1 to 3 is', name[1:3] print 'characters 2 to end is', name[2:] print 'characters 1 to -1 is', name[1:-1] print 'characters start to end is', name[:] [0:-1]   左闭右开 索引同样可以是负数,在那样的情况下,位置是从序列尾开始计算的 切片操作符是序列名后跟一个方括号,方括号中有一对可选的数字,并用冒号分割,数是可选的,而冒号是必须的。 切片操作符中的第一个数(冒号之前)表示切片开始的位置,第二个数(冒号之后)表示切片到哪里结束。如果不指定第一个数,Python就从序列首开始。如果没有指定第二个数,则Python会停止在序列尾。注意,返回的序列从开始位置 开始 ,刚好在 结束 位置之前结束。即开始位置是包含在序列切片中的,而结束位置被排斥在切片外。 (34).引用 当你创建一个对象并给它赋一个变量的时候,这个变量仅仅 引用 那个对象,而不是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的绑定。 代码示例 print 'Simple Assignment' shoplist = ['apple', 'mango', 'carrot', 'banana'] mylist = shoplist # mylist is just another name pointing to the same object! del shoplist[0] print 'shoplist is', shoplist print 'mylist is', mylist
del mylist[0]
print 'shoplist is', shoplist
print 'mylist is', mylist
删除mylist[0]也会改变shoplist print 'Copy by making a full slice' mylist = shoplist[:] del mylist[0] # remove first item print 'shoplist is', shoplist print 'mylist is', mylist   (35).对象的深拷贝与浅拷贝 代码示例 import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象   b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷贝 d = copy.deepcopy(a) #对象拷贝,深拷贝   a.append(5) #修改对象a a[4].append('c') #修改对象a中的['a', 'b']数组对象   print 'a = ', a print 'b = ', b print 'c = ', c print 'd = ', d   (36).其它常用字符串的操作 代码示例 name = 'Swaroop' # This is a string object if name.startswith('Swa'): print 'Yes, the string starts with "Swa" ' if 'a' in name: print 'Yes, it contains the string "a" ' if name.find('war') != -1: print 'Yes, it contains the string "war" ' delimiter = '_*_' mylist = ['Brazil', 'Russia', 'India', 'China'] print delimiter.join(mylist) 2.对象 (37).self等于java的this 当你调用这个对象的方法 MyObject.method()的时候,这会由Python自动转为MyClass.method(MyObject),所以如果你有一个不需要参数的方法,你还是得给这个方法定义一个self参数。   创建一个类 代码示例 class Person: pass # An empty block   p = Person()   有方法的对象 代码示例 class Person: def sayHi(self): print 'Hello, how are you?'   p = Person() p.sayHi() (38).__init__方法 __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。注意,这个名称的开始和结尾都是双下划线。 类似于java的构造函数   代码示例 class Person: def __init__(self, name): self.name = name   #d定义了name并且赋值   def sayHi(self): print 'Hello, my name is', self.name   p = Person('Swaroop') p.sayHi() print p (39).类变量与对象的变量 有两种类型的 域 ——类的变量和对象的变量,它们根据是类还是对象 拥有 这个变量而区分。类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。   对象的变量 由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。 代码示例 class Person: '''Represents a person.''' population = 0   def __init__(self, name): '''Initializes the person's data.''' self.name = name print '(Initializing %s)' % self.name # When this person is created, he/she # adds to the population Person.population += 1   def __del__(self): '''I am dying.''' print '%s says bye.' % self.name Person.population -= 1 if Person.population == 0: print 'I am the last one.' else: print 'There are still %d people left.' % Person.population   def sayHi(self): '''Greeting by the person. Really, that's all it does.''' print 'Hi, my name is %s.' % self.name   def howMany(self): '''Prints the current population.''' if Person.population == 1: print 'I am the only person here.' else: print 'We have %d persons here.' % Person.population   swaroop = Person('Swaroop') swaroop.sayHi() swaroop.howMany() kalam = Person('Abdul Kalam') kalam.sayHi() kalam.howMany() swaroop.sayHi() swaroop.howMany() print   这里,population属于Person类,因此是一个类的变量。name变量属于对象(它使用self赋值)因此是对象的变量。 可以用类名或对象名或self来访问类变量,但是对象的变量和方法通常用对象名或self来访问 我们还看到docstring对于类和方法同样有用。我们可以在运行时使用Person.__doc__和Person.sayHi.__doc__来分别访问类与方法的文档字符串。 如同__init__方法一样 方法__del__,它在对象消逝的时候被调用。但是很难保证这个方法究竟在 什么时候 运行。如果你想要指明它的运行,你就得使用del语句。 Python中所有的类成员(包括数据成员)都是公共的,如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称 管理体系会有效地把它作为私有变量。   方法私有 类属性私有 __population = 0 通用命名规范 如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。 import * 就不会导入它 (40).继承 与java中的继承概念一样,同样能用子类为父类创建实例,但有一些不同
代码示例 class SchoolMember: '''Represents any school member.''' def __init__(self, name, age): self.name = name self.age = age print '(Initialized SchoolMember: %s)' % self.name   def tell(self): '''Tell my details.''' print 'Name:"%s" Age:"%s"' % (self.name, self.age),   class Teacher(SchoolMember): '''Represents a teacher.''' def __init__(self, name, age, salary): SchoolMember.__init__(self, name, age) self.salary = salary print '(Initialized Teacher: %s)' % self.name   def tell(self): SchoolMember.tell(self) print 'Salary: "%d"' % self.salary   class Student(SchoolMember): '''Represents a student.''' def __init__(self, name, age, marks): SchoolMember.__init__(self, name, age)                 #super(self.__class__, self).__init__(name,age)   使用这种方法父类得继承object self.marks = marks print '(Initialized Student: %s)' % self.name   def tell(self): SchoolMember.tell(self) print 'Marks: "%d"' % self.marks   t = Teacher('Mrs. Shrividya', 40, 30000) s = Student('Swaroop', 22, 75) print # prints a blank line members = [t, s] for member in members: member.tell() # works for both Teachers and Students 为了使用继承,我们把基本类的名称作为一个元组跟在定义类时的类名称之后。然后,基本类的__init__方法把子类的self变量传递过去,这样我们就可以初始化对象的基本类部分。这一点十分重要——Python不会自动调用基本类的constructor,你得亲自专门调用它。
  我们还观察到我们在方法调用之前加上类名称前缀,然后把self变量及其他参数传递给它。 注意,在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student的实例仅仅作为SchoolMember的实例。 另外,在这个例子中,我们调用了子类型的tell方法,而不是SchoolMember类的tell方法。可以这样来理解,Python总是首先查找对应类型的方法。如果它不能在子类中找到对应的方法,它才开始到基本类中逐个查找。
基本类是在类定义的时候,在元组之中指明的。如果在继承元组中列了一个以上的类,那么它就被称作 多重继承 。   3.输入/输出 (41).文件 通过创建一个file类的对象来打开一个文件,分别使用file类的read、readline或write方法来恰当地读写文件。对文件的读写能力依赖于你在打开文件时指定的模式。最后,当你完成对文件的操作的时候,你调用close方法来告诉Python我们完成了对文件的使用。 代码示例 poem = '''\ Programming is fun When the work is done if you wanna make your work also fun: use Python! ''' f = file('poem.txt', 'w') # open for 'w'riting写 f.write(poem) # write text to file f.close() # close the file f = file('poem.txt') # if no mode is specified, 'r'ead mode is assumed by default读 while True: line = f.readline() if len(line) == 0: # Zero length indicates EOF break print line, # Notice comma to avoid automatic newline added by Python f.close() # close the file java的自动关闭是怎么回事????? with open方式:https://www.cnblogs.com/ymjyqsx/p/6554817.html
with open('/path/to/file', 'r') as f:
    print(f.read())
通过指明我们希望打开的文件和模式来创建一个file类的实例。 1)、r 打开只读文件,该文件必须存在。  2)、r+ 打开可读写的文件,该文件必须存在。  3)、w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。  4)、w+ 打开可读写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。  5)、a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。  6)、a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。  7)、上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。   如果我们没有指定模式,读模式会作为默认的模式。 因为从文件读到的内容已经以换行符结尾,所以我们在print语句上使用逗号来消除自动换行。最后,我们用close关闭这个文件。   (42).对象持久化 Python提供一个标准的模块,称为pickle。使用它你可以在一个文件中储存任何Python对象,之后你又可以把它完整无缺地取出来。这被称为 持久地 储存对象。 还有另一个模块称为cPickle,它的功能和pickle模块完全相同,只不过它是用C语言编写的,因此要快得多(比pickle快1000倍)。你可以使用它们中的任一个,而我们在这里将使用cPickle模块。记住,我们把这两个模块都简称为pickle模块 代码示例 import cPickle as p #import pickle as p shoplistfile = 'shoplist.data' # the name of the file where we will store the object shoplist = ['apple', 'mango', 'carrot'] # Write to the file f = file(shoplistfile, 'w') p.dump(shoplist, f) # dump the object to a file f.close() del shoplist # remove the shoplist # Read back from the storage f = file(shoplistfile) storedlist = p.load(f) print storedlist   使用了import..as语法。这是一种便利方法,类似于SQL中的别名 4.异常 (43).使用try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中 代码示例 import sys try: s = raw_input('Enter something --> ') except EOFError: print '\nWhy did you do an EOF on me?' sys.exit() # exit the program except: print '\nSome error/exception occurred.' # here, we are not exiting the program   print 'Done' except从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理 所有的 错误和异常。对于每个try从句,至少都有一个相关联的except从句。   你还可以让try..except块关联上一个else从句。当没有异常发生的时候,else从句将被执行。   (44).引发异常 你可以使用raise语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接导子类。 代码示例 class ShortInputException(Exception): '''A user-defined exception class.''' def __init__(self, length, atleast): Exception.__init__(self) self.length = length self.atleast = atleast   try: s = raw_input('Enter something --> ') if len(s) < 3: raise ShortInputException(len(s), 3) # Other work can continue as usual here except EOFError: print '\nWhy did you do an EOF on me?' except ShortInputException, x: print 'ShortInputException: The input was of length %d, \ was expecting at least %d' % (x.length, x.atleast) else: print 'No exception was raised.'   在except从句中,提供了错误类和用来表示错误/异常对象的变量。 (45).try..finally 代码示例 import time try: f = file('poem.txt') while True: # our usual file-reading idiom line = f.readline() if len(line) == 0: break time.sleep(2) print line, finally: f.close() print 'Cleaning up...closed the file' time.sleep方法可以暂停2秒钟。程序运行可以手动用ctrl+c暂停   5.python常用的标准库 (46).sys模块 sys.argv 命令行参数 sys.exit() 退出python程序 sys.version/version_info Python的版本信息 sys.stdin、sys.stdout和sys.stderr它们分别对应你的程序的标准输入、标准输出和标准错误流 sys.path    python的"classpath"   (47).os模块 这个模块包含普遍的操作系统功能。如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的。即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux和Windows下运行。一个例子就是使用os.sep可以取代操作系统特定的路径分割符。   下面列出了一些在os模块中比较有用的部分。它们中的大多数都简单明了。 ● os.name字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。 ● os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径。 ● os.getenv()和os.putenv()函数分别用来读取和设置环境变量。 ● os.listdir()返回指定目录下的所有文件和目录名。 ● os.remove()函数用来删除一个文件。 ● os.system()函数用来运行shell命令。比如os.system("ls -all /") ● os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使用'\n'。 ● os.path.split()函数返回一个路径的目录名和文件名。 >>> os.path.split('/home/swaroop/byte/code/poem.txt') ('/home/swaroop/byte/code', 'poem.txt') ● os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。 ● os.path.exists()函数用来检验给出的路径是否真地存在。 ● os.sep获得当前系统的路径分割符
6.补充内容 (48).特殊的方法 比如__init__和__del__方法,特殊的方法都被用来模仿某个行为。例如,如果你想要为你的类使用x[key]这样的索引操作(就像列表和元组一样),那么你只需要实现__getitem__()方法就可以了。     一些特殊的方法
名称 说明
__init__(self,...) 这个方法在新建对象恰好要被返回使用之前被调用。
__del__(self) 恰好在对象要被删除之前调用。
__str__(self) 在我们对对象使用print语句或是使用str()的时候调用。
__lt__(self,other) 当使用 小于 运算符(<)的时候调用。类似地,对于所有的运算符
(+,>等等)都有特殊的方法。
__getitem__(self,
key)
使用x[key]索引操作符的时候调用。
__len__(self) 对序列对象使用内建的len()函数的时候调用。

(49).单语句块 代码示例 if True: print 'Yes' (50).列表综合
代码示例 listone = [2, 3, 4] listtwo = [2*i for i in listone if i > 2] print listtwo 满足条件(if i > 2)的数指定了一个操作(2*i),从而导出一个新的列表。注意原来的列表并没有发生变化。在很多时候,我们都是使用循环来处理列表中的每一个元素,而使用列表综合可以用一种更加精确、简洁、清楚的方法完成相同的工作。 (51).在函数中接收元组和列表 当要使函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用*和**前缀。这种方法在函数需要获取可变数量的参数的时候特别有用。 代码示例 def powersum(power, *args): '''Return the sum of each argument raised to specified power.''' total = 0 for i in args: total += pow(i, power) return total   print powersum(2, 3, 4) print powersum(2, 10)   在args变量前有*前缀,所有多余的函数参数都会作为一个元组存储在args中。如果使用的是**前缀,多余的参数则会被认为是一个字典的键/值对。 元组*   字典** 注意[key,value]有[]   (52).lambda lambda语句被用来创建新的函数对象,并且在运行时返回它们。 代码示例 def make_repeater(n): return lambda s: s*n twice = make_repeater(2) print twice('word') print twice(5)   lambda需要一个参数,后面仅跟单个表达式作为函数体,而表达式的值被这个新建的函数返回。注意,即便是print语句也不能用在lambda形式中,只能使用表达式 (53).exec和eval语句 exec语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。下面是一个简单的例子。 exec 'print "Hello World"' eval语句用来计算存储在字符串中的有效Python表达式。下面是一个简单的例子。 eval('2*3') (54).assert语句 assert语句用来声明某个条件是真的。例如,如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert语句是应用在这种情形下的理想语句。当assert语句失败的时候,会引发一个AssertionError。 mylist = ['item'] assert len(mylist) >= 1 mylist.pop()   assert len(mylist) >= 1 (55).repr函数 repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。 i = [] i.append('item') i ['item'] repr(i) "['item']" 基本上,repr函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr__方法来控制你的对象在被repr函数调用的时候返回的内容。   7.参考术语表 argument 实参 attribute 属性 base class 基本类 block 块 character 字符 class 类 comment 注释 complex number 复数 derived class 导出类 dictionary 字典 escape sequence 转义符 exception 异常 expression 表达式 field 域 float 浮点数 function 函数 identifier 标识符 indentation 缩进 indexing 索引 instance 实例 integer 整数 list 列表 list comprehension 列表综合 literal constant 字面意义上的常量 logical line 逻辑行 long integer 长整数 method 方法 module 模块 namespace 名称空间 object 对象 operand 操作数 operator 运算符 parameter 形参 pickle 储存器 physical line 物理行 sequence 序列 shebang line 组织行 slicing 切片 statement 语句 string 字符串 subclass 子类 superclass 超类 tuple 元组 type 类型 variable 变量

标签:__,shoplist,name,对象,self,基础知识,print,部分,python2
来源: https://www.cnblogs.com/singsong-ss/p/13031283.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有