本文共 24763 字,大约阅读时间需要 82 分钟。
---------2018.1.24------------
round是向上取整,引用方式为round(number[,ndigits])
而floor是向下取整,floor函数通过import math导入,引用方式为math.floor(number)
str函数,它会把值转换成合理形式的字符串,函数原型为str(object)//字符串要用双引
号引起来,数字不需要repr函数,它会创建一个字符串.以合法的Python表达式的形式来表示值,函数原型为repr
(object)如果你希望打印一个包含数字的句子,加上``(反引号)可以很方便的输出
input()与raw_input()区别
input()会假设用户输入的是合法的python表达式,例如字符串一定要用引号引起来
而raw_input()会把所有的输入当作原始数据将其放入字符串中
如果你需要写一个非常长的字符串,需要跨越多行,可以使用三个引号(单引号和双引号均
可)代替.如果一行中最后一个字符是反斜杠\,那么换行符本身就"转义"了,也就是被忽略了.
原始字符串r'x'或者r"x",几乎可以输出任何字符,唯一不行的就是原始字符串最后的一个
字符不能是反斜杠,要输出反斜杠\,只有对原反斜杠\进行转义,形式为'\\'pow(x,y[,z]) 返回x的y次幂(所得结果对z取模)
---------2018.2.6------------
利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()
方法
1 # -*- coding: utf-8 -*- 2 def trim(s): 3 if s[:1] != ' ' and s[-1:] != ' ': 4 return s 5 elif s[:1] == ' ': 6 return trim(s[1:]) 7 else: 8 return trim(s[:-1]) 9 # 测试:10 if trim('hello ') != 'hello':11 print('测试失败!')12 elif trim(' hello') != 'hello':13 print('测试失败!')14 elif trim(' hello ') != 'hello':15 print('测试失败!')16 elif trim(' hello world ') != 'hello world':17 print('测试失败!')18 elif trim('') != '':19 print('测试失败!')20 elif trim(' ') != '':21 print('测试失败!')22 else:23 print('测试成功!')
的移动可以用递归函数非常简单地实现。
请编写move(n, a, b, c)
函数,它接收参数n
,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法,例如:
1 def move(n,a,b,c):2 if(n==1):3 print(a,'-->',c)4 else:5 move(n-1, a, c, b)6 move(1, a, b, c)7 move(n-1, b, a, c)8 move(3, 'A' , 'B', 'C')
请使用迭代查找一个list中最小和最大值,并返回一个tuple:
1 # -*- coding: utf-8 -*- 2 def findMinAndMax(L): 3 length=len(L) 4 if(length==0): 5 return (None,None) 6 elif(length==1): 7 return (L[0],L[0]) 8 else: 9 minn=L[0]10 maxn=L[0]11 for x in L:12 if(x>=maxn):13 maxn=x14 if(x<=minn):15 minn=x16 return (minn,maxn)17 # 测试18 if findMinAndMax([]) != (None, None):19 print('测试失败!')20 elif findMinAndMax([7]) != (7, 7):21 print('测试失败!')22 elif findMinAndMax([7, 1]) != (1, 7):23 print('测试失败!')24 elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9):25 print('测试失败!')26 else:27 print('测试成功!')
定义如下:
1 / \ 1 1 / \ / \ 1 2 1 / \ / \ / \ 1 3 3 1 / \ / \ / \ / \ 1 4 6 4 1 / \ / \ / \ / \ / \1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
1 # -*- coding: utf-8 -*- 2 def triangles(): 3 a = [1] 4 while True: 5 yield a 6 a = [sum(i) for i in zip([0] + a, a + [0])] 7 8 # 期待输出: 9 # [1]10 # [1, 1]11 # [1, 2, 1]12 # [1, 3, 3, 1]13 # [1, 4, 6, 4, 1]14 # [1, 5, 10, 10, 5, 1]15 # [1, 6, 15, 20, 15, 6, 1]16 # [1, 7, 21, 35, 35, 21, 7, 1]17 # [1, 8, 28, 56, 70, 56, 28, 8, 1]18 # [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]19 n = 020 results = []21 for t in triangles():22 print(t)23 results.append(t)24 n = n + 125 if n == 10:26 break27 if results == [28 [1],29 [1, 1],30 [1, 2, 1],31 [1, 3, 3, 1],32 [1, 4, 6, 4, 1],33 [1, 5, 10, 10, 5, 1],34 [1, 6, 15, 20, 15, 6, 1],35 [1, 7, 21, 35, 35, 21, 7, 1],36 [1, 8, 28, 56, 70, 56, 28, 8, 1],37 [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]38 ]:39 print('测试通过!')40 else:41 print('测试失败!')
1 # -*- coding: utf-8 -*-2 L1 = ['Hello', 'World', 18, 'Apple', None]3 L2 = [s.lower() for s in L1 if isinstance(s,str)==True]4 # 测试:5 print(L2)6 if L2 == ['hello', 'world', 'apple']:7 print('测试通过!')8 else:9 print('测试失败!')
split翻译为分裂。 split()就是将一个字符串分裂成多个字符串组成的列表。
split()当不带参数时以空格进行分割,当代参数时,以该参数进行分割。
//---当不带参数时
example:
st0= ' song huan gong '
print(st0.split())
结果为:
['song', 'huan', 'gong']
结论:当不带参数时,默认是以空格作为参数,不管空格在哪,或者有几个 全部被镐掉了!
//---当带参数时 这种情况就不能按照上面的方式去理解了
example:
st0= 'iisongiiihuaniiiigongi'
print(st0.split('i'))
结果为:
['', '', 'song', '', '', 'huan', '', '', '', 'gong', '']
分析:
这个结果可能就有点出乎意料了并不是想象中的['song', 'huan', 'gong'] 而是多了很多空字符串元素'',这个怎么理解呢? 我的理解方式是,当带参数时,我们得把字符串想象成一块五花肉,我们要做 一件奇葩的事情,就是将肥肉丢到垃圾桶,把瘦肉留下。 比如'iisongiiihuaniiiigongi'这串五花肉,'i'就是要丢掉的肥肉,每次还只能切 'i'这么多。 切的时候是从左到右,一刀下去肥肉'i'丢掉,刀刃左边的部分拿走作为list的一个元素, 刀刃右边的就是剩下的,那么继续切剩下的部分,直到切完。
'iisongiiihuaniiiigongi'这块肉比较特殊:
其一、他的开始和结尾都有i,而且i还不止一个!这样按照上述的方法就会切出 空气,就是列表中我们看到的'', 空字符串元素。 如'iisongiiihuaniiiigongi',当第一刀下去的时候,第一个i被丢到了垃圾桶, 而刀刃的左边什么都没有,所以列表的第一个元素就是'',空字符串元素。 一刀下去之后,就剩下'isongiiihuaniiiigongi'。 所以第二刀下去之后,又得到一个空字符串元素,目前“肉”就剩下'songiiihuaniiiigongi'。 第三刀又切掉一个i,那么刀刃左边的就是song,所以第三个元素就是'song'。 直到切到最后,整坨肉就只剩下一个i了,使用最后一刀下去i被切掉了,刀刃的左边此时也 什么都没有了,所以最后一个元素任然是空字符串。
一个超级好的例子:
1 >>> str="hello boy<[www.doiido.com]>byebye"2 >>> str.split("[")[1].split("]")[0]3 'www.doiido.com'4 >>> str.split("[")[1].split("]")[0].split(".")5 ['www', 'doiido', 'com']
利用map
和reduce
编写一个str2float
函数,把字符串'123.456'
转换成浮点数123.456
:
1 # -*- coding: utf-8 -*- 2 from functools import reduce 3 DIGITS = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} 4 def char2num(s): 5 return DIGITS[s] 6 def str2float(s): 7 s=s.split('.') 8 if len(s[0])==0: 9 s[0]='0'10 return reduce(lambda x,y:x*10+y,map(char2num,s[0]))+reduce(lambda x,y:x*10+y,map(char2num,s[1]))*pow(0.1,len(s[1]))11 print('str2float(\'123.456\') =', str2float('123.456'))12 if abs(str2float('123.456') - 123.456) < 0.00001:13 print('测试成功!')14 else:15 print('测试失败!')
Python提供的sum()
函数可以接受一个list并求和,请编写一个prod()
函数,可以接受一个list并利用reduce()
求积:
1 # -*- coding: utf-8 -*-2 from functools import reduce3 def prod(L):4 return reduce(lambda x,y:x*y,L)5 print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))6 if prod([3, 5, 7, 9]) == 945:7 print('测试成功!')8 else:9 print('测试失败!')
利用map()
函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT']
,输出:['Adam', 'Lisa', 'Bart']
:
1 # -*- coding: utf-8 -*-2 def normalize(name):3 name=name[0].upper()+name[1:].lower()4 return name5 # 测试:6 L1 = ['adam', 'LISA', 'barT']7 L2 = list(map(normalize, L1))8 print(L2)
回数是指从左向右读和从右向左读都是一样的数,例如12321
,909
。请利用filter()
筛选出回数:
1 # -*- coding: utf-8 -*- 2 def is_palindrome(n): 3 nn = str(n) #转成字符串 4 return nn == nn[::-1] #反转字符串并对比原字符串返回true/false 5 # 测试: 6 output = filter(is_palindrome, range(1, 1000)) 7 print('1~1000:', list(output)) 8 if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]: 9 print('测试成功!')10 else:11 print('测试失败!')
---------2018.2.7------------
请把下面的Student
对象的gender
字段对外隐藏起来,用get_gender()
和set_gender()
代替,并检查参数有效性:
1 # -*- coding: utf-8 -*- 2 class Student(object): 3 def __init__(self, name, gender): 4 self.name = name 5 self.gender = gender 6 def get_gender(self): 7 return self.gender 8 def set_gender(self,gender): 9 if gender=='male' or gender=='female':10 self.gender=gender11 else:12 raise ValueError('gender error')13 # 测试:14 bart = Student('Bart', 'male')15 if bart.get_gender() != 'male':16 print('测试失败!')17 else:18 bart.set_gender('female')19 if bart.get_gender() != 'female':20 print('测试失败!')21 else:22 print('测试成功!')
2018/3/5
ubuntu16.04自带python的环境,不用进行python环境安装,
在安装好环境的虚拟机中,提供了py2,py3,django_py2,tornado_py2,spider_py2,django_py3的虚拟环境mysql安装
sudo apt-get install mysql-serversudo apt-get install libmysqlclient-dev注意安装server端的时候会提示输入密码,记住这个密码。然后通过命令登入数据库redis安装
sudo apt-get install redis-server通过redis-cli登入mongoDB安装详情请参考 http://blog.csdn.net/zgf19930504/article/details/52045600postgresql安装sudo apt-get install postgresqlsudo apt-get install libpq-develasticsearch安装(django项目使用)sudo apt-get install elasticsearch其它依赖包sudo apt-get install python-dev 3.django环境安装我们将虚拟环境所需的包全部放在install.txt,以下是django_py3项目所需环境:django==1.7.4jsonfieldPillow==2.8.2celeryamqp==1.4.9anyjson==0.3.3billiard==3.3.0.23celery==3.1.23decorator==4.0.10Django==1.7.8django-haystack==2.5.0django-redis-sessions==0.5.6ipdb==0.8.1ipython-genutils==0.1.0jsonfield==1.0.3kombu==3.0.35psycopg2==2.6.2pytz==2016.6.1redis==2.10.5setuptools==25.1.0wheel==0.29.0执行pip3 install -r instal.txt命令即可 4.tornado环境安装在tornado_py2虚拟环境中安装:ipython==4.2.0ipython-genutils==0.1.0pingpp==2.0.11pycrypto==2.6.1qiniu==7.0.7redis==2.10.5requests==2.10.0tornado==4.3MySQL-python==1.2.5SQLAlchemy==1.0.14 5.spider环境安装在spider_py2虚拟环境中安装:attrs==16.0.0backports-abc==0.4backports.ssl-match-hostname==3.5.0.1BeautifulSoup==3.2.1beautifulsoup4==4.4.1boto==2.38.0certifi==2016.2.28cffi==1.7.0chardet==2.3.0CherryPy==3.5.0click==6.6cryptography==1.4cssselect==0.9.2cssutils==1.0Cython==0.24decorator==4.0.6Django==1.8.7dnspython==1.12.0easydict==1.6enum34==1.1.6feedparser==5.1.3greenlet==0.4.10html5lib==0.999idna==2.1ipaddress==1.0.16ipython==2.4.1jieba==0.38jsonpath==0.54lxml==3.5.0Markdown==2.6.6mechanize==0.2.5motor==0.2motorengine==0.9.0mysqlclient==1.3.7ndg-httpsclient==0.4.0netifaces==0.10.4nltk==3.2.1parsel==1.0.2pbr==1.9.1pexpect==4.0.1Pillow==3.3.0pip==8.1.2pkg-resources==0.0.0poster==0.8.1ptyprocess==0.5pyasn1==0.1.9pyasn1-modules==0.0.8pybloomfilter==1.0pybloomfiltermmap==0.3.12pycparser==2.14pycrypto==2.6.1PyDispatcher==2.0.5Pygments==2.1pymongo==2.7pyOpenSSL==16.0.0python-dateutil==2.4.2pytz==2014.10PyYAML==3.11queuelib==1.4.2redis==2.10.5repoze.lru==0.6requests==2.10.0Routes==2.2rq==0.6.0Scrapy==1.1.0scrapy-redis==0.6.3scrapyd==1.1.0scrapyd-client==1.0.1selenium==2.53.6service-identity==16.0.0setuptools==25.1.0simplegeneric==0.8.1singledispatch==3.4.0.3six==1.10.0sqlparse==0.1.18stevedore==1.13.0tornado==4.3Twisted==16.2.0urllib3==1.13.1w3lib==1.14.2WebOb==1.5.1wheel==0.29.0zope.interface==4.2.0
编译C语言代码(基于Vim编辑器)
vi 1.c
i插入代码 上下左右还是可以使用HJKL或者up down left right(建议使用HJKL)写完保存退出ESC+:xgcc 1.c编译 会生成a.out文件运行a.out文件命令:./a.outpython3支持中文编码,python2不支持中文编码
要解决python2不支持中文编码的操作为:# -*- coding=utf-8 -*-特别注意:
python2中input的意思是把交互式输入的东西当成代码去执行,而python3中默认当作字符串去输入而如果要让python2中输入的东西当作字符串,我们需要用到raw_input()比如a=input("请输入你的名字:")
请输入你的名字:laowangpython2中会报错,python3则不会请输入你的名字:1+2print(a)python2中打印结果为3 python3中打印结果为'1+2'而python2中要实现打印字符串,用raw_input函数a=raw_input("请输入你的名字:")请输入你的名字:1+2print(a)'1+2' 由于在python3中默认input类型为字符串类型,如果我们需要获取int类型,我们需要设置一个变量去存储字符串类型例如age_num=int(age) 变量名不能使用关键字import keyword
keyword.kwlist显示当前版本的所有关键字print("%d%s%f"%(a,b,c))
不等于在python2和python3中通用写法是!=
但是在python2中还有一种写法是<>,这个意思也是表示不等于vi编辑代码的时候,如果之前有定义的变量,敲完该变量的一部分,再敲上Ctrl+n自动补全
if not (条件):
print(xxx) 意思是不在条件范围内if not (x>0 and x<50): print("hello")逻辑运算符:
and 且or 或not 非if 条件1:
print(a)elif 条件2: print(aa)......else: print(aaa)while 条件:
a=b+c print(c) 打印不换行:print("xxx(打印信息)",end="")打印换行:print("") 复合赋值运算符:+=-=*=/=%=**=//=而不能使用j++之类的,这是错误的语法,只能写成j+=1在进行复合赋值运算时,=后面的数字不管进行什么运算,切记加上小括号
举个例子:
a=2a*=3+2答案是10,计算方式是a=a*(3+2)=2*5=10,而并不是a=2*3+2=8import random
random.randint(0,2)意思是导入一个random的库,random.randint(0,2)意思是随机生成0-2中的整数
切片:
name[2:6]取的是从第二个位置开始(下标从0开始),到小于第六个位置为止(第五个位置)name[2:]
取的是从第二个位置开始(下标从0开始),取到最后一个name[2:-1:2]
取的是从第二个位置开始(下标从0开始),取到最后一个的前面一个,步长为2,就是每两个位置取一个切片:[起始位置:终止位置:步长](针对字符串而言)
起始位置取大于等于号,终止位置取小于号
步长可以为负数步长为负数时是倒着取值,反向,相当于取逆序数
find函数,意思是找到我们需要的字符串的首字符的下标,找不到输出-1str="hello world"
str.find("world")>>6 str.find("Hello")>>-1index函数 和find查找函数一样 找到了返回 只不过find没找到返回-1 index没有找到直接返回异常
rindex 返回子字符串 str 在字符串中最后出现的位置 如果没有匹配的字符串会报异常rfind 返回字符串最后一次出现的位置,如果没有匹配项则返回-1
count 用于统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。 replace 把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。split 通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串
str.split(str="", num=string.count(str)).str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等num -- 分割次数str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );>>['Line1-abcdef', 'Line2-abc', 'Line4-abcd']capitalize 将字符串的第一个字母变成大写,其他字母变小写。对于 8 位字节编码需要根据本地环境。
s = ' a, B' # a 前面有空格
s.capitalize()>>' a, b' title 所有单词都是以大写开始,其余字母均为小写str.title()startswith 用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False。如果参数 beg 和 end 指定值,则在指定范围内检查。
endswith 用于判断字符串是否以指定后缀结尾,如果以指定后缀结尾返回True,否则返回False。可选参数"start"与"end"为检索字符串的开始与结束位置。
lower 转换字符串中所有大写字符为小写str.lower()upper 将字符串中的小写字母转为大写字母
str.upper()rjust 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串。如果指定的长度小于字符串的长度则返回原字符串。
ljust 返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串。如果指定的长度小于原字符串的长度则返回原字符串。
center 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。默认填充字符为空格。
lstrip 用于截掉字符串左边的空格或指定字符
rstrip 删除 string 字符串末尾的指定字符(默认为空格)
strip 用于移除字符串头尾指定的字符(默认为空格)
partition 用来根据指定的分隔符将字符串进行分割。
rpartition 从后往前查找,返回包含字符串中分隔符之前、分隔符、分隔符之后的子字符串的tuple;如果没找到分隔符,返回字符串和两个空字符串
splitlines 字符串以换行符为分隔符拆分,去掉换行符;如果keepends为True,保留换行符
isalpha 检测字符串是否只由字母组成
isdigit 检测字符串是否只由数字组成
join 用于将序列中的元素以指定的字符连接生成一个新的字符串
str = "-";
seq = ("a", "b", "c"); # 字符串序列print str.join( seq );>>a-b-cappend 用于在列表末尾添加新的对象 如果添加的对象是列表 则会整体添加
list.append(obj)ps:
a=[1,2]b=[3,4]a.extend(b)>>[1,2,3,4]a.append(b)>>[1,2,[3,4]]insert 用于将指定对象插入列表的指定位置
list.insert(index, obj)
extend 用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.extend(seq)
pop 用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 删除最后一个list.pop(obj=list[-1])remove 用于移除列表中某个值的第一个匹配项 根据内容来删除
list.remove(obj)
del xxx[下标] 根据下标来删除
in 操作符用于判断键是否存在于列表/字典中,如果键在列表/字典里返回true,否则返回false
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。
字典通过键来查找 info={键1:值1,键2:值2,......} 添加xxx[新的key] = value
删除
del xxx[key]
修改
xxx[已存在的key] = new_value
查询
xxxx.get(key)
for...else结构:如果for循环里面有break,不触发else
如果for循环里面没有break 一定会触发elseappend 注意点:
a=[1,2]b=[3,4]a=a.append(b)
进行这一步操作后,a的值为None了原因是进行a.append(b)操作后,b的值已经添加到a里面去了 结果已经发生变化了 但是我们单独敲a.append(b)这句话时,
并没有任何输出 这就说明a.append(b)这步操作的值为空 a.append(b)整体结果为没有 没有输出就没有结果 反而你把这个传入a a的值只能保存为空 即为None在python2中
keys 以列表返回一个字典所有的键
ps:dict.keys()
values 以列表返回字典中的所有值
ps:dict.values()
items 以列表返回可遍历的(键, 值) 元组数组
ps:dict.items()
而python3中
会返回一个生成器 一个对象 内容是列表的形式
example:
在python2中:
info={"name":"laowang","age":18}info.keys()>>['name','age']而在python3中
info={"name":"laowang","age":18}info.keys()>>dict_keys(['name','age']) 拆包举个例子就知道了:
下面是元组拆包a=(11,22)c,d=ac>>11d>>22 在items中取值时,两种取值方式 一种是用数组下标 一种是元组拆包举个例子:
info={"name":"laowang","age":18}for temp in info.items(): print("key=%s,value=%s"%(temp[0],temp[1]))info={"name":"laowang","age":18}
for A,B in info.items(): print("key=%s,value=%s"%(A,B))以上两种方式得出的结果相同
元组:(小括号)
字典:很多信息描述一个物体(大括号)
列表:存储不同物体的相同信息(中括号) 元组类型的数据不能修改里面的值,相当于一个只读文件而列表可以修改值
函数:
def 函数名: ...一个函数想要返回多个数值,可以将其打包成元组或者列表
return a,b,c 相当于封装成元组返回 写代码规范:写函数时,先写结构,再去考虑里面内容代码能够重复使用
全局变量与局部变量注意点:
1.如果全局变量中定义了某个量 如果还想在函数中对这个变量进行修改的话 在函数中使用global对全局变量进行一个声明
那么这个函数中的变量就不是定义一个局部变量 而是对全局变量进行修改2.全局变量定义得放在函数调用之前
#注释会被忽略文档字符串(doctoring)"""XXX"""可以被调用(不影响程序的执行)def main 完成对整个程序的控制 main函数需要定义
main()调用主函数 python代码一般格式:# -*-coding=utf-8-*-import xxxdef xxx(aa): ...xxx(aa) 列表 字典的注意事项:如果列表 字典当作全局变量 可以不需要在函数中定义global,加了也没事 但是单纯的变量在函数中一定需要加上global
缺省参数:在函数中传入默认值 在调用函数时可以不传入那个变量值 那个参数称为缺省参数example:
def test(a,b=22): result = a+b print("result=%d"%result)test(11)test(22,33)test(44)>>33
>>55>>66而像test(11,b=22)
b=22为命名参数不定长参数
如果我们需要调用一个传入任意个参数的函数 怎么办呢
我们这时候采用传入*args 函数的形参 告诉python解释器 传入的实参个数如果大于形参真正的个数 剩下的统统扔给args比如我们有10个苹果要分给三个人 有个人是你的亲属 需要你照顾他 每个人发完一个后 剩余的都给需要照顾的人输出的结果为元组
example:
def sum(a,b,*args): print(a) print(b) print(args)sum(1,2,3,4,5,6,7,8)
>>1>>2>>(3,4,5,6,7,8) 对于上面这个例子 如果传入的实参只有2个 也不会错 args的值为空 输出的时候会输出一个()(空的元组) **kwargs以字典的形式保存 输出结果为字典形式多余参数不带变量名的 统统给args 多余参数带变量名的 统统给kwargs
def sum(a,b,*args,**kwargs):
print(a) print(b) print(args) print(kwargs)sum(1,2,3,4,5,6,task=88,done=78)
1
2(3, 4, 5, 6){'task': 88, 'done': 78}
拆包:
就是在实参上加上*/** 把一个列表/字典拆成一个一个值 元组/列表拆成一个一个元素 字典拆成 key value 这个过程就是拆包
用法:如下例子
def sum(a,b,*args,**kwargs):
print(a) print(b) print(args) print(kwargs)A=(44,55,66)/[44,55,66]
B={"name":"laowang","age":18}
sum(11,22,*A,**B) 在实参上写了*/** 意思是拆包
>>
1122(44, 55, 66){'name': 'laowang', 'age': 18} id 用于获取对象的内存地址id([object]) a=1 意思并不是说定义了一个变量 而是贴了个标签,这个标签是内存地址b=a 这个意思也是把a的内存地址给b 所以id查看会发现a,b的内存地址相同
而C语言不是 C语言是定义变量 只是值相等 地址不同
只要a的值改变了 b的值也会改变 python有自动回收垃圾机制 数字是不可变类型 字符串也是不可变类型 元组也是个不可变类型举个例子
a="hello"a[0]>>'h'a[0]='H'报错。。。说明字符串不允许修改
列表和字典属于可变类型 在定义时不允许当key用 infors.sort(key=lambda x:x['name']) 匿名函数 lambda eval 用来执行一个字符串表达式,并返回表达式的值eval(expression[, globals[, locals]])
交换两个数a=a+b
b=a-ba=a-b任何语言都适用
a,b=b,a python独特写法 两数交换
列表加上列表 等于 列表的合并 误区:python里面不是值赋值,而是引用赋值
例子:
num+=num与num=num+num的区别
由于python里面时引用赋值
假设num=100传入一个求解两个数的和的函数num+=num 传入的实参num指向100这个值
所以做修改时直接修改的是num本身的值
修改的是全局变量
而num = num + num传入参数时 num定义的是临时变量此时num指向的是100+100=200
文件的读入f = oepn("test.py","r") 意味着通过open打开文件 用f进行操作文件的读写
r 文件必须存在
w 文件如果不存在 就创建新文件a 打开一个文件 从文件的末尾写rb
wbab有b结尾说明是二进制文件文本文件与二进制文件区别
r+
w+a++表示你可以读写文件rb+
wb+ab+open默认以读入的方式打开 所以可以不写"r"
seek 用于移动文件读取指针到指定位置fileObject.seek(offset[, whence])
f.seek(2,0) 0表示文件的开头 2表示跳过开头两个位置开始读如果我已经读完了一个文件 想要重新读取该文件
我们应该用f.seek(0,0)拉回来 让该文件还能调用f.read()重新读取
f.tell() 返回文件的当前位置,即文件指针当前位置
fileObject.tell(offset[, whence])
open 支持相对路径和绝对路径
面向过程 考虑要面面俱到 强调的是过程
而面向对象则不需要 找个有这样能力的人去做 强调的是对象形象的解释
对象 看的见摸得着 实实在在的东西类是模型 一个概念
类由三部分组成
类的名称:类名
类的属性:一组数据
类的方法:允许对进行操作的方法(行为)
比如:类名:Tank
属性:重量 速度 材料方法:开炮 移动 转弯 在类中定义方法的时候参数位置要写上self 执行 Cat() 在内存中申请了空间 返回对象的引用而执行 tom = Cat() tom是创建的对象的引用
指向那个对象
添加属性
tom.name="xxx" 给tom添加属性name
tom.age=xx 给tom添加属性age
例子:类Cat
tom=Cat()
tom.调用方法
tom.添加属性
class Cat:
#属性#方法
def eat(self): print("猫在吃鱼....")def drink(self):
print("猫正在喝kele.....")def introduce(self):
#print("%s的年龄是:%d"%(tom.name, tom.age)) print("%s的年龄是:%d"%(self.name, self.age))
#创建一个对象
tom = Cat()#调用tom指向的对象中的 方法
tom.eat()tom.drink()#给tom指向的对象添加2个属性
tom.name = "汤姆"tom.age = 40#获取属性的第1种方式
#print("%s的年龄是:%d"%(tom.name, tom.age))tom.introduce()#相当于 tom.introduce(tom)
lanmao = Cat()lanmao.name = "蓝猫"lanmao.age = 10lanmao.introduce()
self的作用:
你通过哪个对象去调用方法 self就指向哪个对象tom.introduce() 相当于tom.introduce(tom)
而如果class中函数的形参不写入self 直接调用tom.introduce()
结果会显示多传入了一个参数 这个就是原因所在
还有 不一定要传入形参的时候传self a b c等任何数都行 只是我们约定俗成 用self
魔法方法1:__init__方法:初始化对象
def __init__(self): pass 初始化对象创建对象的过程:
1.创建一个对象2.python会自动的调用__init__方法3.返回创建的对象的引用给tom__init__也称为魔法方法
class Cat: """定义了一个Cat类"""#初始化对象
def __init__(self, new_name, new_age): self.name = new_name self.age = new_age#方法
def eat(self): print("猫在吃鱼....")def drink(self):
print("猫正在喝kele.....")def introduce(self):
print("%s的年龄是:%d"%(self.name, self.age))#创建一个对象
tom = Cat("汤姆", 40)tom.eat()tom.drink()#tom.name = "汤姆"#tom.age = 40tom.introduce()lanmao = Cat("蓝猫", 10)
#lanmao.name = "蓝猫"#lanmao.age = 10lanmao.introduce() 1.创建对象name = "汤姆"age = 402.调用__init__方法
3.返回这个对象的引用 1.创建对象name = "蓝猫"age = 102.调用__init__方法3.返回这个对象的引用 魔法方法2:__str__用来获取对象描述信息
def __self__(self): return xxxprint(tom)
打印出xxx(调用tom的信息)
class Cat: """定义了一个Cat类"""#初始化对象
def __init__(self, new_name, new_age): self.name = new_name self.age = new_agedef __str__(self):
return "%s的年龄是:%d"%(self.name, self.age)#方法
def eat(self): print("猫在吃鱼....")def drink(self):
print("猫正在喝kele.....")def introduce(self):
print("%s的年龄是:%d"%(self.name, self.age))#创建一个对象
tom = Cat("汤姆", 40)lanmao = Cat("蓝猫", 10)
print(tom)print(lanmao) 打印结果为:汤姆的年龄是40蓝猫的年龄是10
通过全局变量 通过属性 来进行数据的共享
把函数的功能封装起来
def __test(self): pass这种方式是方法私有化
del不是真正删除了 而是删除了引用
def __del__(self): passpython解释器调用
class Dog:
def __del__(self): print("-----英雄over------")dog1 = Dog()
dog2 = dog1del dog1#不会调用 __del__方法,因为这个对象 还有其他的变量指向它,即 引用计算不是0
del dog2#此时会调用__del__方法,因为没有变量指向它了print("====================")#如果在程序结束时,有些对象还存在,那么python解释器会自动调用它们的__del__方法来完成清理工作
测量一个对象引用的计数方式:使用sys模块中的getrefcount函数
import sys
class T: passt = T()
sys.getrefcount(t)
>>2tt = t
sys.getrefcount(tt)>>3del tt
sys.getrefcount(t)>>2 父类/基类继承
子类/派生类
我们定义了一个Animal类 父类/基类下面有个Dog Cat的子类
Dog下面定义了一个wangcai的方法 tom的方法
wangcai只能使用Dog Animal类中的方法
tom只能使用Cat Animal类中的方法不允许出现tom使用Dog中的方法
或者是wangcai使用Cat中的方法 重写 在子类中重写父类的方法调用的时候只会调用子类的方法
super().bark()
super调用被重写的父类的方法
私有方法 私有的属性并不会被继承
如果调用的是继承的父类中的共有方法 可以在这个公有方法中访问父类中的私有属性和私有方法
但是如果在子类中实现了一个公有方法 那么这个方法是不能够调用继承的父类中的私有方法
class Base(object): pass class Base(object): def test(self): print("----Base")class A(Base):
def test(self): print("-----A")class B(Base):
def test(self): print("-----B")class C(A,B):
pass #def test(self): # print("-----C") c = C()c.test()print(C.__mro__)
类名.__mro__决定调用一个方法的时候 搜索的顺序 如果在某个类中找到了方法 那么就停止搜索 定义的时候对象不确定 调用的时候确定对象 这个方法叫多态 python既支持面向过程 也支持面向对象python面向对象的三个基本要素是 封装 继承 多态
一个特殊的属性 能够知道这个对象的class 类在程序里面也是一个对象 称为类对象由类创建出的对象为实例对象
实例对象的属性为实例属性 实例属性和对象有关系类对象中的属性为类属性 类属性和类有关系
类属性是共享的
实例属性:和具体的某个实例对象有关系并且 一个实例对象和另外一个实例对象是不共享属性的类属性:类属性所属于类对象
并且多个实例对象之间共享同一个 类属性class Tool(object):
#类属性
num = 0#方法
def __init__(self, new_name): #实例属性 self.name = new_name #对类属性+=1 Tool.num += 1 tool1 = Tool("铁锹")tool2 = Tool("工兵铲")tool3 = Tool("水桶")print(Tool.num)
实例方法 类方法 静态方法class Game(object):
#类属性
num = 0#实例方法
def __init__(self): #实例属性 self.name = "laowang"#类方法
@classmethod def add_num(cls): cls.num = 100#静态方法
@staticmethod def print_menu(): print("----------------------") print(" 穿越火线V11.1") print(" 1. 开始游戏") print(" 2. 结束游戏") print("----------------------")game = Game()
#Game.add_num()#可以通过类的名字调用类方法game.add_num()#还可以通过这个类创建出来的对象 去调用这个类方法print(Game.num)#Game.print_menu()#通过类 去调用静态方法
game.print_menu()#通过实例对象 去调用静态方法 @classmethod 装饰器 固定写法 通过一个类进行分离解耦在父类中不去实现 在子类中实现
这就是工厂方法模式
def __new__(cls):
pass当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径
class Dog(object): def __init__(self): print("----init方法-----")def __del__(self):
print("----del方法-----")def __str__(self):
print("----str方法-----") return "对象的描述信息"def __new__(cls):#cls此时是Dog指向的那个类对象
#print(id(cls))
print("----new方法-----")
return object.__new__(cls) #print(id(Dog))xtq = Dog()
1.创建一个对象
2.调用__init__方法3.返回对象的引用而__new__方法就是重写父类的new方法
1.调用__new__方法来创建对象,然后找了个变量来接受__new__返回值,这个返回值表示 创建出来的对象的引用2.__init__(刚刚创建出来的对象的引用) 初始化
3.返回对象的引用
而构造方法是既创建对象 又初始化 和__init__方法不等价__new__只负责创建对象 __init__只负责初始化
class Dog(object):__instance = None
def __new__(cls):
if cls.__instance == None: cls.__instance = object.__new__(cls) return cls.__instance else: #return 上一次创建的对象的引用 return cls.__instancea = Dog()
print(id(a))b = Dog()print(id(b)) class Dog(object):__instance = None
__init_flag = Falsedef __new__(cls, name):
if cls.__instance == None: cls.__instance = object.__new__(cls) return cls.__instance else: #return 上一次创建的对象的引用 return cls.__instancedef __init__(self, name):
if Dog.__init_flag == False: self.name = name Dog.__init_flag = True a = Dog("旺财")print(id(a))print(a.name)b = Dog("哮天犬")
print(id(b))print(b.name)
异常处理:
try:
except 出现异常的名字:
try: print(num)except NameError: print(111)
Exception
如果用了Exception,那么意味着只要上面的except没有捕获到异常 这个except一定会捕获到
Exception 不管产生什么异常 都会捕获到 就不需要去写许多异常了 异常方面很多as 预处理方案 会给出产生该异常的原因
#coding=utf-8
try:
num = input("xxx:") int(num) #11/0 #open("xxx.txt") #print(num) print("-----1----")except (NameError,FileNotFoundError):
print("如果捕获到异常后做的 处理....")except Exception as ret: print("如果用了Exception,那么意味着只要上面的except没有捕获到异常,这个except一定会捕获到") print(ret)else: print("没有异常才会执行的功能")finally: print("------finally-----")print("-----2----")
Ctrl + C也是一个异常自定义异常类
raise引发一个自定义的异常 log日志 会记录发生的异常 *.py文件就是模块 .pyc 字节码的后缀 翻译后的python代码 from 模块名 import 功能名1,功能名2,.....从模块中导入功能1,功能2,等等from 模块名 import * 从模块中导入所有功能
这种方式缺陷:如果导入的模块的功能名相同 后面导入的会覆盖前面导入的
import msg
msg.text1()通过模块名.功能名调用
import time as tt 导入time模块 给它取个名字 叫tttt.sleep(3)不取和模块名相同的名字
import xxx
class ClassName(object):
def __init__(self,arg): passdef xxx():
pass def main(): passif __name == '__main__':
main()__all__ = ["功能名1","功能名2",...../或者类名也行]
定义的作用:放上将来你想要用的功能/类名,如果没放进去 调用import仍不能用
把模块有关联的放在一个文件夹中
在python2中调用文件夹名会直接失败
在python3中调用会成功,但是调用不能成功解决办法是:
在该文件夹下加入空文件__init__.py python2会把该文件夹整体当成一个包
然后编辑__init__.py加入__all__ = ["功能名1","功能名2",...../或者类名也行]
再通过from 模块名 import *
通用写法是:from . import 模块名这样就可以调用包中那些模块功能了
#如果导入这个模块的方式是 from 模块名 import * ,那么仅仅会导入__all__的列表中包含的名字
setup.py
from distutils.core import setup
setup(name="dongGe", version="1.0", description="dongGe's module", author="dongGe", py_modules=['TestMsg.sendmsg', 'TestMsg.recvmsg'])
模块的发布过程:1.创建文件setup.py 传入模块.功能2.python3 setup.py build3.python3 setup.py dist4.生成压缩包,然后可以发布到github.com上系统安装包
sudo python3 setup.py install python2中range(10)返回值是一个列表[0,...,9]而在python3中返回值是range(0,10)range(0,10)在python2中返回是一个列表[0,...,9]
而在python3中返回值是range(0,10) range有风险 如果将来你需要一个很大的值 因为需要占用很大的空间 所以不给你 如果python3中想要返回值是一个列表使用a = [i for i in range(1,18)] 这样可以返回一个列表
在python2中这种写法也适合(参数1,参数2,参数3,.....) for 参数1 in range(第1个数) for 参数2 in range(第2个数) 。。。。。。。
set 字典list 列表
while True:
1.检测事件,如果有时间就控制相应的图片移动2.把所有的图片重新画一遍1/60s --> 动画效果
列表循环删除的时候不能删除循环的那个列表 我们可以申请一个新的列表去存
您可以考虑给博主来个小小的打赏以资鼓励,您的肯定将是我最大的动力。thx.
微信打赏
支付宝打赏
作 者: 出 处: 关于作者:潜心机器学习以及信息安全的综合研究。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者我 声援博主:如果您觉得文章对您有帮助,可以点击右下角【】推荐一下该博文。您的鼓励是作者坚持原创和持续写作的最大动力!