---------2018.1.24------------css
round是向上取整,引用方式爲round(number[,ndigits])html
而floor是向下取整,floor函數經過import math導入,引用方式爲math.floor(number)html5
str函數,它會把值轉換成合理形式的字符串,函數原型爲str(object)//字符串要用雙引
號引發來,數字不須要python
repr函數,它會建立一個字符串.以合法的Python表達式的形式來表示值,函數原型爲repr
(object)mysql
若是你但願打印一個包含數字的句子,加上``(反引號)能夠很方便的輸出git
input()與raw_input()區別github
input()會假設用戶輸入的是合法的python表達式,例如字符串必定要用引號引發來redis
而raw_input()會把全部的輸入看成原始數據將其放入字符串中sql
若是你須要寫一個很是長的字符串,須要跨越多行,可使用三個引號(單引號和雙引號均
可)代替.數據庫
若是一行中最後一個字符是反斜槓\,那麼換行符自己就"轉義"了,也就是被忽略了.
原始字符串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=x 14 if(x<=minn): 15 minn=x 16 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 = 0 20 results = [] 21 for t in triangles(): 22 print(t) 23 results.append(t) 24 n = n + 1 25 if n == 10: 26 break 27 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'這塊肉比較特殊:
其1、他的開始和結尾都有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 reduce 3 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 name 5 # 測試: 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=gender 11 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-server
sudo apt-get install libmysqlclient-dev
注意安裝server端的時候會提示輸入密碼,記住這個密碼。而後經過命令登入數據庫
redis安裝
sudo apt-get install redis-server
經過redis-cli登入
mongoDB安裝
詳情請參考 http://blog.csdn.net/zgf19930504/article/details/52045600
postgresql安裝
sudo apt-get install postgresql
sudo apt-get install libpq-dev
elasticsearch安裝(django項目使用)
sudo apt-get install elasticsearch
其它依賴包
sudo apt-get install python-dev
3.django環境安裝
咱們將虛擬環境所需的包所有放在install.txt,如下是django_py3項目所需環境:
django==1.7.4
jsonfield
Pillow==2.8.2
celery
amqp==1.4.9
anyjson==0.3.3
billiard==3.3.0.23
celery==3.1.23
decorator==4.0.10
Django==1.7.8
django-haystack==2.5.0
django-redis-sessions==0.5.6
ipdb==0.8.1
ipython-genutils==0.1.0
jsonfield==1.0.3
kombu==3.0.35
psycopg2==2.6.2
pytz==2016.6.1
redis==2.10.5
setuptools==25.1.0
wheel==0.29.0
執行pip3 install -r instal.txt命令便可
4.tornado環境安裝
在tornado_py2虛擬環境中安裝:
ipython==4.2.0
ipython-genutils==0.1.0
pingpp==2.0.11
pycrypto==2.6.1
qiniu==7.0.7
redis==2.10.5
requests==2.10.0
tornado==4.3
MySQL-python==1.2.5
SQLAlchemy==1.0.14
5.spider環境安裝
在spider_py2虛擬環境中安裝:
attrs==16.0.0
backports-abc==0.4
backports.ssl-match-hostname==3.5.0.1
BeautifulSoup==3.2.1
beautifulsoup4==4.4.1
boto==2.38.0
certifi==2016.2.28
cffi==1.7.0
chardet==2.3.0
CherryPy==3.5.0
click==6.6
cryptography==1.4
cssselect==0.9.2
cssutils==1.0
Cython==0.24
decorator==4.0.6
Django==1.8.7
dnspython==1.12.0
easydict==1.6
enum34==1.1.6
feedparser==5.1.3
greenlet==0.4.10
html5lib==0.999
idna==2.1
ipaddress==1.0.16
ipython==2.4.1
jieba==0.38
jsonpath==0.54
lxml==3.5.0
Markdown==2.6.6
mechanize==0.2.5
motor==0.2
motorengine==0.9.0
mysqlclient==1.3.7
ndg-httpsclient==0.4.0
netifaces==0.10.4
nltk==3.2.1
parsel==1.0.2
pbr==1.9.1
pexpect==4.0.1
Pillow==3.3.0
pip==8.1.2
pkg-resources==0.0.0
poster==0.8.1
ptyprocess==0.5
pyasn1==0.1.9
pyasn1-modules==0.0.8
pybloomfilter==1.0
pybloomfiltermmap==0.3.12
pycparser==2.14
pycrypto==2.6.1
PyDispatcher==2.0.5
Pygments==2.1
pymongo==2.7
pyOpenSSL==16.0.0
python-dateutil==2.4.2
pytz==2014.10
PyYAML==3.11
queuelib==1.4.2
redis==2.10.5
repoze.lru==0.6
requests==2.10.0
Routes==2.2
rq==0.6.0
Scrapy==1.1.0
scrapy-redis==0.6.3
scrapyd==1.1.0
scrapyd-client==1.0.1
selenium==2.53.6
service-identity==16.0.0
setuptools==25.1.0
simplegeneric==0.8.1
singledispatch==3.4.0.3
six==1.10.0
sqlparse==0.1.18
stevedore==1.13.0
tornado==4.3
Twisted==16.2.0
urllib3==1.13.1
w3lib==1.14.2
WebOb==1.5.1
wheel==0.29.0
zope.interface==4.2.0
編譯C語言代碼(基於Vim編輯器)
vi 1.c
i插入代碼 上下左右仍是可使用HJKL或者up down left right(建議使用HJKL)
寫完保存退出ESC+:x
gcc 1.c編譯 會生成a.out文件
運行a.out文件命令:./a.out
python3支持中文編碼,python2不支持中文編碼
要解決python2不支持中文編碼的操做爲:
# -*- coding=utf-8 -*-
特別注意:
python2中input的意思是把交互式輸入的東西當成代碼去執行,而python3中默認看成字符串去輸入
而若是要讓python2中輸入的東西看成字符串,咱們須要用到raw_input()
好比a=input("請輸入你的名字:")
請輸入你的名字:laowang
python2中會報錯,python3則不會
請輸入你的名字:1+2
print(a)
python2中打印結果爲3 python3中打印結果爲'1+2'
而python2中要實現打印字符串,用raw_input函數
a=raw_input("請輸入你的名字:")
請輸入你的名字:1+2
print(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=2
a*=3+2
答案是10,計算方式是a=a*(3+2)=2*5=10,而並非a=2*3+2=8
import 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函數,意思是找到咱們須要的字符串的首字符的下標,找不到輸出-1
str="hello world"
str.find("world")
>>6
str.find("Hello")
>>-1
index函數 和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-c
append 用於在列表末尾添加新的對象 若是添加的對象是列表 則會總體添加
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 必定會觸發else
append 注意點:
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=a
c
>>11
d
>>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 xxx
def 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) 在實參上寫了*/** 意思是拆包
>>
11
22
(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-b
a=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
wb
ab
有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 = 10
lanmao.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 = 40
tom.introduce()
lanmao = Cat("藍貓", 10)
#lanmao.name = "藍貓"
#lanmao.age = 10
lanmao.introduce()
1.建立對象
name = "湯姆"
age = 40
2.調用__init__方法
3.返回這個對象的引用
1.建立對象
name = "藍貓"
age = 10
2.調用__init__方法
3.返回這個對象的引用
魔法方法2:__str__
用來獲取對象描述信息
def __self__(self):
return xxx
print(tom)
打印出xxx(調用tom的信息)
class Cat:
"""定義了一個Cat類"""
#初始化對象
def __init__(self, new_name, new_age):
self.name = new_name
self.age = new_age
def __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):
pass
python解釋器調用
class Dog:
def __del__(self):
print("-----英雄over------")
dog1 = Dog()
dog2 = dog1
del dog1#不會調用 __del__方法,由於這個對象 還有其餘的變量指向它,即 引用計算不是0
del dog2#此時會調用__del__方法,由於沒有變量指向它了
print("====================")
#若是在程序結束時,有些對象還存在,那麼python解釋器會自動調用它們的__del__方法來完成清理工做
測量一個對象引用的計數方式:
使用sys模塊中的getrefcount函數
import sys
class T:
pass
t = T()
sys.getrefcount(t)
>>2
tt = t
sys.getrefcount(tt)
>>3
del 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.__instance
a = Dog()
print(id(a))
b = Dog()
print(id(b))
class Dog(object):
__instance = None
__init_flag = False
def __new__(cls, name):
if cls.__instance == None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
#return 上一次建立的對象的引用
return cls.__instance
def __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模塊 給它取個名字 叫tt
tt.sleep(3)
不取和模塊名相同的名字
import xxx
class ClassName(object):
def __init__(self,arg):
pass
def xxx():
pass
def main():
pass
if __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 build
3.python3 setup.py dist
4.生成壓縮包,而後能夠發佈到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 --> 動畫效果
列表循環刪除的時候不能刪除循環的那個列表 咱們能夠申請一個新的列表去存