Python語法概念基礎詳解

  • (本章節主要是一些python的基礎語法,具體內容不夠詳細,以pycharm下調試產生的部分代碼為主)
  • (python語法的詳細內容請參考官方教程或者經典書籍)
  • (在架構方面來看,或者程序的設計思路來看,語法並不是一個很重要的東西,語法部分過於細節,而且很多很繁雜;但是對於程序或者功能的實現來說,語法概念卻是基礎,是程序的血肉,隻有熟練掌握語法的基礎知識,才能更好更快速的寫好程序)

Python之禪:

'''
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
•優美勝於醜陋(Python 以編寫優美的代碼為目標)
•明瞭勝於晦澀(優美的代碼應當是明瞭的,命名規范,風格相似)
•簡潔勝於復雜(優美的代碼應當是簡潔的,不要有復雜的內部實現)
•復雜勝於凌亂(如果復雜不可避免,那代碼間也不能有難懂的關系,要保持接口簡潔)
•扁平勝於嵌套(優美的代碼應當是扁平的,不能有太多的嵌套)
•間隔勝於緊湊(優美的代碼有適當的間隔,不要奢望一行代碼解決問題)
•可讀性很重要(優美的代碼是可讀的)
•即便假借特例的實用性之名,也不可違背這些規則(這些規則至高無上)
•不要包容所有錯誤,除非你確定需要這樣做(精準地捕獲異常,不寫 except:pass 風格的代碼)
•當存在多種可能,不要嘗試去猜測
•而是盡量找一種,最好是唯一一種明顯的解決方案(如果不確定,就用窮舉法)
•雖然這並不容易,因為你不是 Python 之父(這裡的 Dutch 是指 Guido )
•做也許好過不做,但不假思索就動手還不如不做(動手之前要細思量)
•如果你無法向人描述你的方案,那肯定不是一個好方案;反之亦然(方案測評標準)
•命名空間是一種絕妙的理念,我們應當多加利用(倡導與號召)
'''

Python基礎:

1. 進制轉換:

>>> bin(1)
'0b1'
>>> bin(9)
'0b1001'
>>> oct(90)
'0o132'
>>> bin(9)
'0b1001'
>>> bin(1)
'0b1'
>>> oct(10)
'0o12'
>>> oct(9)
'0o11'
>>> hex(14)
'0xe'
>>> hex(15)
'0xf'
>>> 10
10
>>> 11
11
>>> oct(0b10)
'0o2'
>>> oct(0b111)
'0o7'
>>> hex(100)
'0x64'
>>> hex(0b1111)
'0xf'
>>> hex(0o77)
'0x3f'

2. 數據類型:

Python基本數據類型:
數字:整型int,浮點型float,bool型,復數complex
組分為序列,集合,字典
序列(有序(此處有序是指輸入後順序不改變,即不具備自動排序功能),可下標索引,切片操作):字符串str,列表list,元組tuple
集合set:無序(此處的無序是指輸入後set內部進行自己排序,導致序列可能與之前的不同),沒有索引,不能切片
字典dict:({key,value}是其基本概念與形式)
>>> type(1)
<class 'int'>
>>> type(1.1)
<class 'float'>
>>> type((1,1))
<class 'tuple'>
>>> type((1,2))
<class 'tuple'>
>>> type((1,1,1,))
<class 'tuple'>
>>> type([1,1,1,1])
<class 'list'>
>>> type(None)
<class 'NoneType'>
>>> type(36j)
<class 'complex'>
>>> type('a')
<class 'str'>
>>> type("a")
<class 'str'>
>>> type('''a''')
<class 'str'>
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> type(['hello', 'world', 90, True, False])
<class 'list'>
>>> type({})
<class 'dict'>
空集合表示方法:
>>> type(set())
<class 'set'>
>>> type({1,2,3})
<class 'set'>
>>> type({1,'2',3.3,True})
<class 'set'>
需要註意的是True與False的區別(集合是自動排序的):
>>> {1,'2',3.3,True}
{'2', 1, 3.3}
>>> {1,'2',3.3,False}
{'2', 1, 3.3, False}

3. 單雙引號轉義字符的使用:

轉義字符的使用:
當使用IDLE直接輸出時:
例:
'"k"'
輸出:'"k"'
"'k'"
輸出:"'k'"
轉義字符的使用:
單一轉義均可轉(轉雙引號顯示‘',轉單引號顯示“”):
>>> 'lets\'go'
"lets'go"
>>> 'lets\'go''lets\'go'
"lets'golets'go"
>>> 'lets\"go''lets\"go'
'lets"golets"go'
>>> "lets\"go""lets\"go"
'lets"golets"go'
>>> "lets\'golets\'go"
"lets'golets'go"
>>> 'lets\"go'"lets\"go"
'lets"golets"go'
>>> "lets\'go"'lets\'go'
"lets'golets'go"
轉義混合隻轉雙(由於隻轉雙引號,因此全顯示‘'):
>>> "lets\"go""lets\'go"
'lets"golets\'go'
>>> "lets\'go""lets\"go"
'lets\'golets"go'
>>> 'lets\'go''lets\"go'
'lets\'golets"go'
>>> 'lets\"go''lets\'go'
'lets"golets\'go'
>>> "lets\"go"'lets\'go'
'lets"golets\'go'
>>> 'lets\'go'"lets\"go"
'lets\'golets"go'
>>> "lets\'go"'lets\"go'
'lets\'golets"go'
>>> 'lets\"go'"lets'go"
'lets"golets\'go'
print函數直接轉:
>>> print('lets\"go''lets\'go')
lets"golets'go
>>> print('let\'sgolet\'sgo')
let'sgolet'sgo

4.單雙三引號的轉義換行:

引入三引號便於在換行時可繼續輸入:
單雙三引號換行方式:
正常不換行:
>>> 'helloworld helloword'
'helloworld helloword'
三引號(單引號形式)換行:
>>> '''helloword
... '''
'helloword\n'
>>> '''
... hello world
... helloworld
... '''
'\nhello world\nhelloworld\n'
三引號(雙引號形式)換行(與單引號形式的三引號沒有區別):
>>> """hello world
... hello world
... '''
... """
"hello world\nhello world\n'''\n"
>>> """
... helloword
... 'kkk''
... """
"\nhelloword\n'kkk''\n"
>>> """
... hello world
... "kkk""
... """
'\nhello world\n"kkk""\n'
對於轉義字符換行的使用(單雙引號與三引號):
>>> print("""\nhello\nhello""")
hello
hello
>>> print("\nhello\nhello")
hello
hello
print函數也是單雙引號限制在同一行,三引號形式可多行
>>> print("hello
  File "<stdin>", line 1
    print("hello
               ^
SyntaxError: EOL while scanning string literal
>>> print('''hello
... hello''')
hello
hello
在後面加\可在下一行輸入,但是是直接銜接,沒有\n符號:
>>> 'hello\
... hello'
'hellohello'
>>> print('hello
  File "<stdin>", line 1
    print('hello
               ^
SyntaxError: EOL while scanning string literal
>>> print('hello\
... hello')
hellohello

5.字符串的運算:

字符串的運算:
可加性:
>>> 'hello'+'world'
'helloworld'
通過[]下標形式獲取字符串的字符:
>>> 'helloworld'[7]
'r'
>>> 'hello'[0]
'h'
負數時從後面開始計數:
>>> 'hello'[-1]
'o'
>>> 'hello'[-2]
'l'
>>> 'hello'[-4]
'e'
越界:
>>> 'hello'[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>> 'hello'[-10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
字符串的截取(左閉右開區間,截取字符個數為右減左,但是要註意字符串是從0開始的)(格式:字符串後加[左區間:右區間]):
>>> 'helloworld'[0:2]
'he'
>>> 'helloworld'[1:5]
'ello'
我們截取到最後時可以數到最後一位截取,也可以超出規定位數進行截取:
>>> 'hello'[0:5]
'hello'
>>> 'hello'[0:20]
'hello'
負數表示概念:步長(從字符串末尾往回數幾個字符)(負數在截取字符串中表示的含義與獲取字符時相同,但是截取時是左閉右開區間,如果要截到最後一位(序號為-1),就要加一為0,但是實際操作並不是要寫0,可看下面的例子):
>>> 'helloworld'[0:-1]
'helloworl'
>>> 'hellowprld'[0:0]
''
>>> 'hello'[0:]
'hello'
由上面的這個例子可以推出:
>>> 'hello'[:3]
'hel'
由前兩個例子可以得到從頭截取到尾的表示方法:
>>> 'hello'[:]
'hello'
字符串不支持字符串間相乘,但是可以乘數字:
>>> '1'*'1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>> "1"*8
'11111111'

6.組的概念與含義:

組(序列)的概念與含義:
str(字符串),list(列表),tuple(元組)都可以看做序列:
每個元素都有一個序號:
>>> (1,2,3)[1]
2
>>> [1,2,3][1]
2
>>> '123'[1]
'2'
bool類型在序列中的判斷使用:
in / not in:
>>> 3 in [1,2]
False
>>> 3 in (1,2,3)
True
>>> 3in(1,2,3)
True
>>> 3 not in (1,2,3)
False
>>> 3 not in [1,2]
True
註意字符串內判斷要用‘'
>>> '1' in '1234'
True
>>> 2 not in '134'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not int
>>> '2' not in '134'
True
首先要區分元組與列表:
>>> 1,2
(1, 2)
>>> (1,2)
(1, 2)
>>> type((1,2))
<class 'tuple'>
>>> [1,2]
[1, 2]
>>> [[1],[2]]
[[1], [2]]
>>> [[1,2,3],[1,2,3,4,5]]
[[1, 2, 3], [1, 2, 3, 4, 5]]
>>> type([[1],[2]])
<class 'list'>
[[1],[2]],[[1, 2, 3], [1, 2, 3, 4, 5]]又叫嵌套列表,實際就是二維數組
空元組與空列表(元組內表示單個元素時要加逗號,否則直接計算出來變為原來的數據類型):
>>> ((1))
1
>>> ('a')
'a'
>>> ((1,))
(1,)
>>> (1,)
(1,)
>>> ()
()
>>> type((1,))
<class 'tuple'>
>>> type(())
<class 'tuple'>
>>> type([1])
<class 'list'>
>>> type([])
<class 'list'>
列表內的數據類型可以不唯一:
>>> ['hello','world',90]
['hello', 'world', 90]
>>> type(['hello', 'world', 90])
<class 'list'>
>>> ['hello', 'world', 90,True,False]
['hello', 'world', 90, True, False]
>>> type(['hello', 'world', 90, True, False])
<class 'list'>
列表與字符串類似,也具有可加性:
>>> [1,2]+[1]
[1, 2, 1]
列表內元素的獲取(類似於字符串相關截取操作):
>>> [1,2,3,4][2]
3
>>> ['1','2','3'][2]
'3'
>>> ['1','2','3'][0:1]
['1']
>>> [1,'2',3][0:1]
[1]
>>> ['1',2,3][0:1]
['1']
是字符串截取出字符串,是整型截取出整型,數據類型不會變。
需要註意的是,我們用冒號截取一段時,截取結果依然是列表,而我們不使用冒號獲取單一元素時,截取結果的數據類型隻是該元素的數據類型(比如我們截取“3”,那麼截取結果的數據類型就是字符串,結果是‘3')
列表不支持列表間相乘,但是可以乘數字:
>>> [1,2]*[1,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'list'
>>> [1,2]*3
[1, 2, 1, 2, 1, 2]
列表中一些函數的簡單使用(len(),min(),max()等):
>>> len([1,2,3])
3
size是沒有定義的:
>>> size([1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'size' is not defined
>>> max([1,2,3])
3
未知量是無法比較的(並不是字符串的比較,未知量會出錯):
>>> max([a,b,c])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> min(('a','b'))
'a'
>>> max(['a','b'])
'b'
對字符串:
>>> min('abcde')
'a'
>>> max('aaa111ccc')
'c'
>>> min('aaa111ccc')
'1'
>>> min('a b')
' '
上面的例子實際是有輸出的,是空格。
對於元組與列表的比較和對字符串的比較是不同的(字符串的比較是無論多少字符串隻輸出最大或最小的字符,而元組或列表是對每個元素的比較,元素可能就是字符串,那麼就是對字符串的比較):
>>> max('abbcc''bccaa')
'c'
>>> max("abc""def")
'f'
>>> max(["abc","cde"])
'cde'
>>> max(('abc','def'))
'def'
ord()函數是直接輸出字符(單個字母或符號,Python中無字符概念)所對應的ASCII碼:
隻能是單個字符:
>>> ord('we')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 2 found
>>> ord('p')
112
空格所對應的ASCII碼:
>>> ord(' ')
32
單雙引號均可(Python都表示字符串):
>>> ord('0')
48
>>> ord("0")
48

7.集合:

集合(set)也是序列的一種:
集合的運算:
集合支持序列的相關運算,同時不一樣的地方在於:
集合是不允許元素重復的,會自動清除相同元素,同時元素是有序的(默認從小到大),之前的元組以及列表都是無序的。
>>> {1,2,2}
{1, 2}
>>> {1,2,4,3,2}
{1, 2, 3, 4}
>>> {4,3,2,1}
{1, 2, 3, 4}
集合支持減號:(除去集合中相同的項並返回到減號前面的集合)(差集)
>>> {1,2,3}-{1}
{2, 3}
>>> {1,2,3}-{4}
{1, 2, 3}
>>> {1,2,3}-{2,3,4}
{1}
集合支持並和與的計算(交集:&,並集:|):
>>> {1,2,3}&{3}
{3}
>>> {1,2,3}|{4}
{1, 2, 3, 4}
集合與字典:
>>> type({})
<class 'dict'>
空集合的表示方法:
>>> type(set())
<class 'set'>
空集合的長度:
>>> len(set())
0
字典是無序的,字典不屬於序列,無法用下標的形式進行查詢,但是字典存在key值,我們可以通過直接查詢key值來查詢相關元素:
鍵值key是不允許相同的,同時key可以是不同數據類型:
>>> {1:2,1:3}
{1: 3}
>>> {1:2,'1':2}
{1: 2, '1': 2}
>>> {1:2,'1':3}['1']
3
>>> {1:2,'1':3}[1]
2
這裡需要註意的是:value值是可以任意的數據類型,比如str,int,float,tuple,甚至是list,set,dict,但是key值存在限制,key值隻能是不可變對象,比如str,int,float,tuple等,可變對象就不可以是key值,比如list,set,dict。

8.系統關鍵字與引用的可變性和值的不可變性:

系統關鍵字也可以自定義但是系統關鍵字之前的功能就失效瞭
沒有必要給自己挖這樣的坑:
>>> type=1
>>> type(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> 1(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> print(type)
1
當然上面也可以將type改為print,print就失去原來功能。
引用類型是可變的,賦值改變時不新增對象,隻是對原來的對象進行改變,值類型是不可變的,值類型重新賦值時會新增一個對象。
上面註意引用類型的使用
>>> a=3
>>> id(a)
1687645280
>>> b=9
>>> a=a+b
>>> print(a)
12
>>> id(a)
1687645568
>>> a=3
>>> id(a)
1687645280
>>> a=4
>>> id(a)
1687645312
對於str類型也是如此:
(如下圖)
str由於是不可變類型,所以'python'[0]='o'是錯誤的。

在這裡插入圖片描述

9.邏輯運算符:

or and not :
或 且 非:
或隻需一個真就不必往後進行判斷瞭,且是需要判斷到最後才能算出是否為真,因此結果如下:
>>> not True
False
>>> 1 or 2
1
>>> 2 or 3
2
>>> 3 or 4
3
>>> 1 and 2
2
>>> 2 and 3
3
身份運算符(is)判斷內存地址是否相等
相等返回True,反之返回False
判斷類型:
type(a)==int 
如果a是整型返回True
,一般可用isinstance函數:
instance(a,int)
如果a是整型返回True
當然也可以使用ininstance(a,(int,str,float))來進行判斷,看a是否屬於後面給出的其中一類。
對象的三個特征:id、value、type
判斷:is,==,isinstance
位運算:先將十進制數轉化為二進制數
按位與:隻有二進制對應的位都為1時才為1,否則為零
按位或:二進制對應的位有1時就記為1
優先級:not>and>or
系統命令行cmd
調用D盤:D:
dir顯示目錄
執行python文件時:python+文件名

10.分支,條件,循環,枚舉,包,模塊,函數:

'''
一般程序存在智能感知,回車鍵選中自己想要的即可
'''
# if else for while switch
# 註釋方法:
'''
if else for while switch 
'''
'''
mood=True
if mood:
    print('1')
else:
    print('0')
輸出:1
'''
'''
account = '123'
password = '0000'
user_account = input()
user_password = input()
print(user_account)
if (account == user_account) and (password == user_password):
    print('success')
else:
    print('false')
輸入輸出:
123
0000
success
'''
'''
對於常量,python是使用全部大寫(規范)(實際在python中是不存在常量
這個概念的,這裡隻是指不變的量
對於運算符,標識符,以及縮進都比較嚴格
運算符:比如==,要左右都有空格
標識符:冒號:前面不要有空格,逗號,後面留一個空格(在元組,列表等可不用),註釋#前面距離代碼至少兩個空格等
縮進:if else等註意縮進:Tab(四個空格)
snippet 
elif相當於else if 
switch在python沒有語法定義
字典的使用要強於elif
input()函數每次都將接收到的變量認為是字符串
a=input()
type(a)為字符串類型
要使a變為int整數型
使用:a=int(a)
例:
a = input()
print(type(a))
a = int(a)
print(type(a))
if a == 1:
    print('success')
小應用:
當a與b一真一假時,我們要返回真可以使用if else語句實現,也可以使用or來實現
a or b 返回為真的一個
'''
'''
循環語句:
for while
解決無限循環方法:
上面工具欄Run stop終止程序
或者下面窗口欄右擊程序 Close Tab
while循環例:
a = 1
while a <= 10:
    print(a)
    a += 1
else:
    print('EOF!')
while可與else搭配
但是while與else搭配,for與else搭配並不常用,很多語言也沒有這種語法
'''
'''
for循環例:
b = ((1, 2, 3), [1, 3, 2])
for x in b:
    for y in x:
        if y == 2:
            print(y,  end='abc\n')
            break
        print('bbb')
    print('aaa\n', end='')  # print的end本來就默認打出回車鍵,不必繼續打回車,這裡將end改為空''
else:
    print('EOF!', end='\n12345678')
輸出結果:
bbb
2abc  #跳出內循環
aaa
bbb
bbb
2abc  #跳出內循環
aaa
EOF!  #for循環執行結束後執行else語句
12345678
'''
'''
# 當執行指定次數的循環時:
# range()函數,左閉右開區間:
for x in range(1, 11, 1):
    print(x, end=' ')
# 執行結果:1 2 3 4 5 6 7 8 9 10
print('')  # 由於內置回車,因此這裡什麼都不必輸入就會打出一行空行
# 當然對於遞增1位也可以不加後面的1:
for x in range(1, 11):
    print(x, end=' ')
print('')
# 執行結果:1 2 3 4 5 6 7 8 9 10
for x in range(1, 11, 3):
    print(x, end=' | ')
# 執行結果:1 | 4 | 7 | 10 |
print('')
for x in range(11, 1, -3):
    print(x, end=' | ')
# 執行結果:11 | 8 | 5 | 2 |
'''
'''
# range()函數與切片:
# 對於上面的range()函數,如果又有給定的序列等可以使用,則可以搭配len()函數
a = [1, 2, 3, 4]  # 指定序列
for x in range(0, len(a), 2):  # 這裡的len(a)隻是獲取長度,與序列內容無關
    print(a[x], end=' ')
# 執行結果(當上面是x而不是a[x]時):0 2   # 這裡從0到4左閉右開
# 當是a[x]時:1 3  # 就是a[0],a[2]即1,3
# 我們也完全可以使用切片的方式來代替上面的for循環:
# 三個參數,兩個冒號,最後一個參數為步長
b = a[0:len(a):2]  # 這裡就是對序列直接進行切片
print(type(b))  # 這裡b返回的不是序列內的元素,而是返回切片之前的序列類型
print(b)
# 輸出結果:
# <class 'list'>
# [1, 3]
'''
'''
會寫代碼很容易
高性能,封裝性(可復用),抽象能力(編程是現實生活到計算機裡的映射)
不要太直白
美與不美
'''
'''
Python組織結構:
包(物理表現:文件夾),模塊(.py文件),類(java,C#認為一個文件就寫一個類)
包:C#:dll,JAVA:jar包
包可以建立子包,當然包下面的模塊也可以與子包同級
命名空間(文件路徑)
模塊:
首先要建立一個包,必須建立一個特殊的模塊,模塊名叫做__init__.py
如果沒有這樣一個特殊模塊,python就會認為這隻是一個普通的文件夾,而不是一個包
該文件可以什麼都不寫,隻是標註這是一個包,當然也可以像普通文件一樣編寫代碼
該文件名不是.__init__.py,而是包名
比如test包中該模塊就叫test,而不是test.__init__.py
模塊之間的調用:
註意命名空間的添加
一定是模塊的調用(.py文件)
第一種導入(調用)形式:
模塊調用從後往前調用,依次調用執行:
例:
D:\untitled1\python\__init__.py 文件內代碼如下:
import python.c7
print(python.c7.a)
print('__init__.py')
b = input()
print(b)
D:\untitled1\python\c7.py 文件內代碼如下:
a = 1
print('123')
# 該代碼的調用就是先調用.c7後調用python
# 執行過程如下:
123  # 首先執行c7
1  # 然後執行python,打出變量a,下一行繼續打印
__init__.py
2  # 該行為input()輸入的
2  # 調用過程結束,執行當下剩餘代碼
1  
__init__.py
b  # 該行為input()輸入的
b
Process finished with exit code 0
再舉一個例子:
D:\untitled1\c6.py 文件內代碼如下:
import python.c7
print(python.c7.a)
# 該代碼的調用也是先調用.c7後調用python
# 執行過程如下:
123  # 首先執行c7
1  # 然後執行python,打出變量a,下一行繼續打印
__init__.py
b  # 該行為input()輸入的
b  # 調用過程結束,執行當下剩餘代碼
1
Process finished with exit code 0
# 根據上面兩個例子告訴我們__init__.py文件在每次調用該包內文件時都會被自動調用
# 因此,__init__.py文件適合應用於模塊的初始化(可進行對庫的批量導入)
命名空間過長時,可以使用as來進行替代
例如上面的python.c7可以替換為c7或者任何簡單的名字:
格式(這裡將python.c7轉換為c7):import python.c7 as c7
然後就可以使用瞭:例:print(c7.a)
第二種導入(調用)形式:
from 包 import 對象/函數
然後直接使用這些變量名或者函數
當然也可以從包中導入文件,不過這樣使用就跟直接使用import導入文件沒有差別瞭
如果要導入全部變量,其實也可以這樣使用:
from 包 import *
以星號的形式導入全部變量
但是當我們使用這些變量時由於該文件中沒有過出現這些變量名,系統會提示語法錯誤,但實際上仍然是可以運行的
模塊的內置變量,模塊的內置屬性
__all__=['a', 'b']  一定是字符串類型的
然後再利用*進行導入時隻導入列表內存在的元素變量
也可以直接導入多個變量
from c7 import a, b, c
編譯代碼時會自動生成一些文件:
如:__pycache__文件夾以及.cpython-36.pyc等中間編譯文件
如果是VScode編譯器也可以在資源管理器進行隱藏這些文件
PyCharm編譯器直接自動隱藏瞭
Python編碼規范,一行盡量不要超過80個字符
如果要換行可以使用反斜杠\進行換行連接(不過不好看)
建議使用括號來換行
對庫的批量導入:
對庫的批量導入可放在該文件下然後對要導入該庫的文件直接導入包即可(其實包名也就是該文件名)
批量導入不能重復導入(即不能循環導入)
有時候循環導入是不易發現的,可能涉及到多個文件之間導入的閉合,這就需要更細心一點
入口文件的概念
'''
'''
# 函數
IDLE內:
help(函數名)即可查看函數內置操作
也可使用import this查看python之禪
比如round函數,保留到小數點後面幾位(四舍五入原則)
例如:
a = 1.123456
a = round(a, 2)
print(a)
a = round(a, 5)
print(a)
當然上面的一段輸出是有問題的,輸出結果如下:
1.12
1.12
因為a = round(a, 2)這一步a就已經變成瞭1.12,然後繼續執行是無法得到原來的a保留五位小數的結果的
改成下面的:
a = 1.123456
b = round(a, 2)
print(b)
c = round(a, 5)
print(c)
輸出結果:
1.12
1.12346
可以看到round()函數默認為四舍五入
函數的使用:
1.功能性
2.隱藏細節(函數內部細節可能很復雜,但是在使用時不必看其內部結構)
# 但是如果要深入學習或者函數內部出現瞭bug,我們就需要進入函數內部進行查看
3.避免編寫重復的代碼
也可以進行組織代碼,但是面向對象對於組織代碼更合適一些
可自定義函數
函數的定義:
def關鍵字 函數名 (參數列表):
          函數體
函數體內可以返回直接value,如果沒有return,默認返回None空值
自定義函數名如果跟某些系統函數名沖突等容易造成函數循環調用
例:
def print(code):
    print(code)
本來想要打印傳入的參數,但是由於函數名的問題會造成一直調用自身,導致函數無限循環
但是Python也是非常的人性化,當函數循環調用執行到大概1000次左右時會自動停止程序並報錯
當然我們也可以自定義進行設置最大遞歸次數
如何設置:
import sys
sys.setrecursionlimit(遞歸次數)  # 這裡的遞歸次數我們可以自由設定
當然python內部不會過於大瞭,由於計算機系統的原因也不會達到太大
例:
a = 3
b = 2
def add(x, y):
    result = x + y
    return result
print(add(a,b))
print(add(1, 2))
輸出:
5
3
有的函數存在可變參數:如系統的print()函數參數個數不確定
'''
'''
序列解包:
元組索引解包操作(不推薦使用該解包方式,容易亂):
具體使用:
該處的3,6為隨意輸入的數據,對應的輸出結果為9,22:
如下圖:

在這裡插入圖片描述

下面的解包方式都是正確的(對應元素個數要相等):
d = 1, 2, 3
print(type(d))
a, b, c = d
print(a, b, c)
a, b, c = [4, 5, 6]
print(a, b, c)
a = b = c = 1
print(a, b, c)
輸出結果:
<class 'tuple'>
1 2 3
4 5 6
1 1 1
'''
'''
函數參數:
形式參數,實際參數(形參,實參):形參是定義時括號內的參數,實參是調用時括號內的參數
1.必須參數:定義瞭多少個形參就要傳遞多少個實參
2.關鍵字參數:對實參進行標註,然後可以隨意調換實參順序
例:
函數定義:def add(x,y):
函數調用:result = add(y = 3, x = 2)
3.默認參數:在形參上進行操作,當存在實參時,代入該實參,否則代入默認參數(一般傳參數較多時使用,但是不推薦傳入參數過多,當參數過多時可傳入對象)
例:
def test(z, x = 1, y = 2):
    print(x, y, z)
test(3)
輸出:
1 2 3
註意定義函數時必須傳入的參數隻能放到默認參數之前,即默認參數之後不可存在待傳參數
例:
def test(x = 1, y = 2, z):
    print(x, y, z)
test(3)
SyntaxError: non-default argument follows default argument
另外對於調用來說也可以使用關鍵字參數來進行指明傳參量
但是對於關鍵值參數也是不可以將必須參數與默認參數的順序隨意混亂,仍然遵循默認參數之後不可存在必須參數(除非每個參數都是關鍵字參數)
'''

11.面向對象基本知識:

'''
面向對象
有意義的面向對象的代碼
有類不能等同於是面向對象
類的實例化
student = Student()
類最基本的作用:封裝
類下面的函數一定要加self,否則會報錯,而且在使用類內的變量時一定要加self,否則也會報錯
建議類的模塊內隻寫類,不寫類的實例化與調用
如果寫在一起代碼結構會變得非常松散
方法和函數的區別:很多時候已經模糊瞭這兩個概念:
C,C++:函數,java,C#:方法
方法:更多的是面向對象的概念,面向對象更關註的是設計,設計代碼結構,設計封裝
因此方法更多的是設計層面的稱謂
函數:更多的是面向過程的概念,沒有設計層面的意義在裡面
程序運行,過程式的一種稱謂
類是現實世界或思維世界的實體在計算機中的反映
它將數據(數據成員)以及這些數據上的操作(方法)封裝在一起
python內類構造函數在實例化時會自動調用
格式如下:def __init__(self):
默認返回為None,而且隻能返回None,不能返回其他類型
要傳入參數的話寫在構造函數內,而且一旦確定就必須傳入相應實參
構造函數:初始化對象的屬性(特征)
等號左邊為類內變量(數據成員),右邊為形參名
數據成員與形參名可以相等
例:
name = name
而不必非要寫成name =  name1或者name = name_等
之前講到的模塊部分局部變量與全局變量的作用域:
模塊內局部變量不會覆蓋全局變量
(函數的局部變量與模塊的全局變量可重名)
類變量,實例變量的概念(見下面例題)
python尋找機制:
如果要尋找實例變量,如果沒有找到會到類變量內去尋找,如果還是沒有找到,會到類的父類裡面去尋找(繼承)
'''
'''
class Student:  # 在這裡Student後面也可以選擇加上括號,但是加不加無所謂,加上在PyCharm中反而會提示多餘的括號
    name = 'MJG'
    age = 0
    # 類變量
    def __init__(self, name, age):
        self.name = name
        self.age = age
        # 實例變量(必須加上self)(當然self可以是任意的,隻不過使用self是一種常用習慣)
        # 有瞭實例變量的概念,那麼還有實例方法的概念(對象實例可以調用的方法)
student = Student('1', '2')
print(student.name)
print(student.age)
student = Student
print(student.name)
print(student.age)
# 輸出結果:
# 1
# 2
# MJG
# 0
'''
'''
# 如果代碼是下面一段:

class Student:
    name = 'MJG'
    age = 0
    def __init__(self, name, age):
        name = name
        age = age

student = Student('1', '2')
print(student.name)
print(student.age)
# 輸出結果:
# MJG
# 0
# 卻並不是我們想要的'1', '2',這是因為在構造函數內沒有標明self,導致變量隻作用於局部
# 當輸出時找不到對象變量就隻能尋找類變量進行輸出
'''
'''
下面介紹一下變量__dict__(系統內置到對象中保存對象的所有變量):
可通過打印__dict__變量查看對象的所有變量,當然我們也可以打印該類變量打出類內的所有變量
例:
class Student:
    name = 'MJG'
    age = 0
    def __init__(self, name, age):
        self.name = name
        self.age = age

student = Student('1', '2')
print(student.name)
print(student.age)
print(student.__dict__)
print(Student.__dict__)
輸出結果:
1
2
{'name': '1', 'age': '2'}
{'__module__': '__main__', 'name': 'MJG', 'age': 0, '__init__': <function Student.__init__ at 0x000001B3A9AD0048>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
# 分別顯示瞭所有的對象變量與類變量
'''
'''
Python類:
變量:類變量,實例變量
方法:實例方法,類方法,靜態方法
特殊函數:構造函數
實例變量:訪問實例變量在類內必須加上self,否則會出現誤解,導致找不到實例變量
在類外可以直接調用
例:
    def __init__(self, name1, age1):
        self.name = name1
        self.age = age1
        print(self.name)  # 調用實例變量(正確)
        print(name)  # 既不是調用實例變量也不是調用類變量(類變量內雖然存在name變量,但是這並不是調用類變量的方式,依然會報錯)
        print(name1) # 既不是調用實例變量也不是調用類變量(但是這裡並不會報錯,調用的是形參)
        # 調用類變量的兩種方法:
        print(Student.name)  # 訪問類變量(類內類外都可以這樣調用)
        print(self.__class__.name)  # 類變量的調用(類內)
對於類內變量的操作:
    class Student:
    name = 'MJG'
    age = 0
    sum = 0
    def __init__(self, name1, age1):
        self.name = name1
        self.age = age1
        print('name:' + self.name)
        print('age:' + self.age)
        self.__class__.sum += 1
        print('當前sum數:' + str(self.__class__.sum))

student = Student('1', '2')
student__ = Student('3', '4')
print('最後類變量sum:' + str(Student.sum))
輸出:
name:1
age:2
當前sum數:1
name:3
age:4
當前sum數:2
最後類變量sum:2
類方法:
對於類變量我們可以在構造函數或實例方法中進行操作,當然我們完全可以通過類方法來進行操作:
一般來說,對於類變量的操作我們都是放在類方法中去執行,而不是構造函數與實例方法
定義:
標志(裝飾器):@classmethod
類方法代表名:cls(參數列表內),也像實例方法一樣可以更改,但是也是一種習慣性表達
例:
class Student:
    sum = 0
    @classmethod
    def sum_(cls):
        cls.sum += 1
        print(cls.sum)
Student.sum_()  # 類方法就要使用類去調用
但是python也是允許對象去調用類方法的,但是這在實際上是說不通的,一般不建議使用這種方法
# student = Student
# student.sum_()
輸出結果:
1
靜態方法:
定義:
標志(裝飾器):@staticmethod
類方法與實例方法、類方法的區別:
靜態方法沒有像實例方法、類方法那樣要求強制傳入一個默認指定的名字,類方法的cls代表的是類本身,實例方法的self代表的是實例本身
靜態方法沒有這樣一個默認傳入,隻是一個普普通通的方法
總結:
類訪問類變量(OK),實例變量(也OK)
對象訪問類變量,實例變量,都OK
類與對象都可以訪問靜態方法
類方法,實例方法,靜態方法之間的相互訪問:
類方法與靜態方法都不可以訪問實例變量
實例方法與靜態方法都可以訪問類變量

一般不建議使用靜態方法,除非使用的方法非常純粹,與類和對象都沒有太大的關聯
'''
'''
class Student:
    sum = 0
    def __init__(self, name1, age1):
        self.name = name1
        self.age = age1
    # 自動為對象創建新變量sum
    def __sum__(self):
        self.sum += 1
        print(self.sum)
    # 結果由{'name': 'MJG', 'age': '20'}變為:
    # {'name': 'MJG', 'age': '20', 'sum': 1}
student = Student('MJG', '20')
print(student.__dict__)
student.__sum__()
print(student.__dict__)
# 輸出:
# {'name': 'MJG', 'age': '20'}
# 1
# {'name': 'MJG', 'age': '20', 'sum': 1}
'''
'''
***
class Student:
    sum = 0
    def __init__(self, name1, age1, test1, test2):
        self.name = name1
        self.age = age1
        self.test = test1  # 公開
        self.__test = test2  # 私有,這裡允許重名(一個私有,一個公開)
        self.__class__.test = 10  # 調用類變量,如果一開始沒有選擇創建
        Student.__test = 20  # 調用類變量,如果一開始沒有選擇創建(允許重名)(兩種不同的調用類變量的方式)
    # 前面加兩條下劃線,變為私有,類外直接調用該方法會報錯
    def __sum(self):
        self.sum += 1
        print(self.sum)
print(Student.__dict__)  # 最初始時,隻有一個sum變量
student = Student('MJG', '18', 'test1', 'test2')
print(student.__dict__)  # 註意到test是公開的,__test是私有的:{'name': 'MJG', 'age': '18', 'test': 'test1', '_Student__test': 'test2'}
student.__test = 100  # 對象內雖然存在test私有變量,但是這裡並不是正確的訪問私有變量的方式
# 而且就算可以這樣訪問,也不能更改私有變量,因為這兩個類型本身就是不同的,不能賦值,這裡是類外為對象創建瞭新變量__test
print(student.__test)  # 並不是可以訪問私有成員(訪問私有成員的方式也不是這樣),而是上一行已經為對象創建瞭新變量__test(如果上一行沒有創建過程是會報錯的)
print(student.__dict__)  # 加上構造時的test(test1)和__test(私有)(test2)以及新創建的__test變量(形式,並非私有):{'name': 'MJG', 'age': '18', 'test': 'test1', '_Student__test': 'test2', '__test': 100}
# 對類變量:
print(Student.__dict__)# 在構造時就已經創建瞭新的類變量:公開變量:test和私有變量__test(僅測試用)
# {'__module__': '__main__', 'sum': 0, '__init__': <function Student.__init__ at 0x000002BD60FF0048>, '_Student__sum': <function Student.__sum at 0x000002BD60FF01E0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None, 'test': 10, '_Student__test': 20}
# 對對象進行再創建與測試:
student1 = Student('test_name', 'test_age', 'test1.1', 'test2.1')
print(student1.__dict__)
# print(student1.__test)  # 這裡不對其進行創建,是會報錯的
print(Student.__dict__)
# 輸出:
# {'name': 'test_name', 'age': 'test_age', 'test': 'test1.1', '_Student__test': 'test2.1'}
# {'__module__': '__main__', 'sum': 0, '__init__': <function Student.__init__ at 0x000002548D330048>, '_Student__sum': <function Student.__sum at 0x000002548D3301E0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None, 'test': 10, '_Student__test': 20}
強制讀取私有數據成員:
print(student._Student__test)
print(student1._Student__test)
print(Student._Student__test)
# 上面的方法是可以的,但是強行讀取類就沒有瞭意義(python的保護機制是比較弱的,比較簡單)
輸出:
test2
test2.1
20
'''
'''
面向對象的三大特征:
繼承,封裝,多態:
繼承:
一、首先導入一個模塊(一般不用這種方式)
import 模塊名
class Student(模塊名.類名):
二、直接導入模塊下的類
from 模塊名 import 類名
class Student(類名):
繼承後構造:
首先要傳入父類構造函數內的參數
一、顯示調用父類的構造函數
二、(一般這樣操作):super關鍵字:super(子類名, self).__init__(父類構造函數參數表)
(調用父類的方法:super(子類名, self).方法名)
子類內方法可與父類內方法名重名並進行覆蓋
'''

12.運算符優先級問題:

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

13.代碼自動調節工具pep8:

寫一個有用的代碼自動調節工具:
pep8:
安裝方法:
首先在系統命令行輸入:
python -m pip install autopep8
系統會自動下載安裝autopep8
根據提示進行更新等操作即可完成安裝,然後配置autopep8

14.python庫的安裝:

一、(三個python通用的,不過沒試過)
下載編譯好的python擴展庫(不過好像停用瞭)(可以百度一下,很多類似的庫)(一般pip或者搭配鏡像即可):
  http //www lfd.uci.edu/~gohlke/pythonlibs/
  下載完畢後直接解壓放入:
  C:\Python27\Lib\site-packages(對應自己的庫)
  就可以import使用瞭。
  大部分庫都是有的,特別是機器學習類的,很全。
二、cmd pip
python -m pip install 包名
三、Anaconda直接安裝

15.解決pip超時問題:

解決pip超時問題:
問題狀況如下:
 raise ReadTimeoutError(self._pool, None, "Read timed out.")
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
一、(實驗可用有效)
解決辦法(采用鏡像下載)://例如這裡采用豆瓣鏡像,下載wordcloud詞雲庫:
//下載什麼庫就在pip install -i https://pypi.douban.com/simple後面寫什麼
pip install -i https://pypi.douban.com/simple wordcloud
國內鏡像源:
http://pypi.douban.com/ 豆瓣
http://pypi.hustunique.com/ 華中理工大學
http://pypi.sdutlinux.org/ 山東理工大學
http://pypi.mirrors.ustc.edu.cn/ 中國科學技術大學
二、(可用但未嘗試)
可對pip進行時間限制,在指定時間限制內忽略中停止問題(加大下載時間)

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: