python programming learning 2

Part II 是函数、类和文件(读取)的内容

其实我写的都是按Eric的python编程从入门到实践来的

希望这个图床可以用久一点吧….之前的博客图都没了

Function函数:

函数这一部分也同样和C/C++的类似举个最简单的例子就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def greet_(user_name):
print("hello! "+user_name.title())
_=""
while True:
_=input("please enter your name:")
if _=='quit':
print("Exited loop!")
break
greet_(_)
_=""
###in:
wyh
666
quit
###out:
please enter your name:wyh
hello! Wyh
please enter your name:666
hello! 666
please enter your name:quit
Exited loop!

About the parameters of the function:

关于函数参数方面,函数定义用的是形式参数,在函数调用时所用的为实际参数

函数可以多次调用(在实际参数不同的情况下使用较多

In case the function has multiple parameters:

对于函数参数有多个的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def greet_(user1_name,user2_name):
print("hello! "+user1_name.title())
print("hello! "+user2_name.title())
_=""
x=""
while True:
_=input("please enter user1's name:")
if _=='quit':
print("Exited loop!")
break
x=input("please enter user2's name:")
greet_(_,x)
_=""
x=""
###in:
wyh
dyx
lubenwei
55kai
quit
###out:
please enter user1's name:wyh
please enter user2's name:dyx
hello! Wyh
hello! Dyx
please enter user1's name:lubenwei
please enter user2's name:55kai
hello! Lubenwei
hello! 55Kai
please enter user1's name:quit
Exited loop!

注意形参与实参的位置顺序一定要对应

当然也可以使用关键字实参例如上面的代码可以改动为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def greet_(user1_name,user2_name):
print("hello! "+user1_name.title())
print("hello! "+user2_name.title())
_=""
x=""
while True:
_=input("please enter user1's name:")
if _=='quit':
print("Exited loop!")
break
x=input("please enter user2's name:")###改动为将实参的值赋给形参
greet_(user1_name=_,user2_name=x)
_=""
x=""
###输入输出与上面完全一致

Set default values for function parameters:

对函数参数设置默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def greet_(user2_name,user1_name='wyh'):
print("hello! "+user1_name.title())
print("hello! "+user2_name.title())
_=""
x=""
while True:
_=input("Start or quit ?")
if _=='quit':
print("Exited loop!")
break
x=input("please enter user2's name:")
greet_(x)###也可写为-->greet_(user2_name=x)
_=""
x=""
###in:
start
wmw
quit
###out:
Start or quit ?start
please enter user2's name:wmw
hello! Wyh
hello! Wmw
Start or quit ?quit
Exited loop!

须注意的是设置默认值的形参需要在后面,而不能放在前面,会报错:

Non-default argument follows default argument–>非默认参数置于默认参数之后

Function with return value:

For example:

1
2
3
4
5
6
def print_(string_1,string_2):
string_=string_1.title()+" "+string_2
return string_
print(print_('for','example'))
###out:
For example

无需声明返回值类型,一句return直接搞定,想返回啥返回啥

Make the actual parameters available for selection:

让实参变为可选的

1
2
3
4
5
6
7
8
9
10
11
def print_name(first_name,last_name,middle_name=''):
if middle_name:
full_name=first_name+' '+middle_name+' '+last_name
else:
full_name=first_name+' '+last_name
return full_name
print(print_name('ma','teng','hua'))
print(print_name('ma','yun'))
###out:
ma hua teng
ma yun

Pass the list to the function:

向函数传递列表:(函数参数为列表)

1
2
3
4
5
6
7
8
9
def _(names):
for i in names:
print("Hello! "+i.title())
names=['wyh','white','dyx']
_(names)
###out:
Hello! Wyh
Hello! White
Hello! Dyx

不止是读取列表,也可以通过函数修改列表,有点C/C++基础就会

但是同样可以禁止函数修改列表

1
function_name(list_name[:])

并未将列表本身传给参数修改,而是将列表的副本传递给函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
names=['wyh','white','dyx']
def _(names):
names.sort()
_(names)
print(names)
###out:
['dyx', 'white', 'wyh']
###禁止修改后:
names=['wyh','white','dyx']
def _(names):
names.sort()
_(names[:])###修改了此处
print(names)
###Out:
['wyh', 'white', 'dyx']

Pass any number of actual parameters:

传递任意数量的实参:

定义函数时:

1
def function_name(*Formal parameter name)

*是让python创建一个规定名称的空元组,并且收到的所有值都装入此元组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def print_name(*names):
for name in names:
print("Hello! "+str(name))
print_name('wyh','white','dyx')
###Out:
Hello! wyh
Hello! white
Hello! dyx
###错误code:
names=['wyh','white','dyx']
def print_name(*names):
for name in names:
print("Hello! "+str(name))
print_name(names)
###Out:
Hello! ['wyh', 'white', 'dyx']

Store the function in a template:

将函数存储在模板中:

例如,在同一文件夹下,建立pizza.py和making_pizza.py文件,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pizza.py
def make_pizza(size,*toppings):
print("\nMaking a "+str(size)+
"-inch pizza with the following toppings:")
for topping in toppings:
print("- "+topping)
#making_pizza.py
import pizza
pizza.make_pizza(16,'wyh')
pizza.make_pizza(12,'wyh','lubenwei','55kai')

#编译运行making_pizza.py文件后:
Making a 16-inch pizza with the following toppings:
- wyh

Making a 12-inch pizza with the following toppings:
- wyh
- lubenwei
- 55kai

不难看出最重要的是

1
import pizza

导入了pizza.py文件中的函数模板

当编写出import语句并指定模块名时,就可以使用模块中的所有函数,而使用模块module_name中的函数可用下面的语法:

1
module_name.function_name()

Import specific functions:

假如我们想导入module文件中的某一特定函数,那么我们的语法是:

1
from module_name import function_name

而若是想导入任意数量的函数,那么:

1
from module_name import function_1,function_2,function_3

此时使用从module中导入的函数,可以直接用,而不需要:

1
module_name.function_name()

Use as to specify an alias for the function:

在特定的时候我们可以对模板中的函数“取外号”:

1
2
3
4
from pizza import make_pizza as mp

mp(16,'wyh')
......

指定别名的通用语法:

1
from module_name import function_name as fn

Use as to assign an alias to the module:

同样的可以给模块取别名,通用语法:

1
import module_name as mn

Import all the functions in the template:

将模板中所有函数导入的语法:

1
from module_name *

与导入文件相比的好处是在调用函数的写法上简易一些,无需用句点表示法

但是对于非自己编写的大型模块不建议使用这样的方法导入,可能存在函数名称与项目使用名称相重复的情况


Class类:

类的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Dog():###python的约定:首字母大写的名称指的是类
def __init__(self,name,age):#初始化 注意init前后的下划线是两个
self.name=name
self.age=age

def sit(self):
print(self.name.title()+" is now sitting.")

def roll_over(self):
print(self.name.title()+" rolled over!")
my_dog=Dog('white',6)
"""print("..."+my_dog.name.title()+".")
print("..."+str(my_dog.age)+" years old")"""
my_dog.sit()
my_dog.roll_over()
###out:
White is now sitting.
White rolled over!
#将注释内换掉:
class Dog():###python的约定:首字母大写的名称指的是类
def __init__(self,name,age):#初始化 注意init前后的下划线是两个
self.name=name
self.age=age

def sit(self):
print(self.name.title()+" is now sitting.")

def roll_over(self):
print(self.name.title()+" rolled over!")
my_dog=Dog('white',6)
print("..."+my_dog.name.title()+".")
print("..."+str(my_dog.age)+" years old")
"""my_dog.sit()
my_dog.roll_over()
"""
###out:
...White.
...6 years old

大概使用方法即是如此,类可以创建多个实例即被使用多次

给属性指定默认值:

类中的每个属性都必须有初始值,哪怕为0或者空字符串,而设置默认值的方法是在方法

1
__init__()

中指定初始值,例如将上面的方法指定初始值:

1
2
3
4
def __init__(self,name,age):
self.name=name
self.age=age
self.type='dog'

继承:

一个类可以继承另一个类,会自动获得另一个类的所有属性与方法(对象),原有类为父类,继承了父类的类是子类,子类不仅可以继承父类的所有属性与方法,同样可以定义自己的属性与方法。

子类的方法init需要对父类的所有属性赋值

参见下方代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Dog():
def __init__(self,name,age):
self.name=name
self.age=age

def sit(self):
print(self.name.title()+" is now sitting.")

def roll_over(self):
print(self.name.title()+" rolled over!")
class Cat(Dog):##1
def __init__(self,name,age):##2
super().__init__(name,age)
my_cat=Cat('miaomiao',6)
my_cat.sit()
my_cat.roll_over()
###out:
Miaomiao is now sitting.
Miaomiao rolled over!

Dog为父类,Cat为子类

注意点两点:
1:创建子类时,父类必须包含在当前文件中,且位于子类前面,定义子类时,括号内指定父类的名称,方法init接受创建Dog实例所需信息

2:super()是一个特殊函数,将子类与父类关联起来,调用父类的方法,父类==>superclass

重写父类的方法:

对于父类的方法,当不符合子类的实际使用时,可以对其进行重写,可以在子类中定义一个这样的方法,与需要重写的父类方法相同名,这样,python会以子类中的方法为基准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Dog():
def __init__(self,name,age):
self.name=name
self.age=age

def sit(self):
print(self.name.title()+" is now sitting.")

def roll_over(self):
print(self.name.title()+" rolled over!")
class Cat(Dog):
def __init__(self,name,age):
super().__init__(name,age)
def sit(self):
print(self.name.title()+" is sitting !!!")
my_cat=Cat('miaomiao',6)
my_cat.sit()
my_cat.roll_over()
###out:
Miaomiao is sitting !!!
Miaomiao rolled over!

导入类:

与导入函数类似的:

在一个文件下同时创建两个.py文件,使用下面语法便可在文件中调用另一文件(模块文件)中的类:

1
from base_module_file_name import base_file_name

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#class_.py:
class Dog():
def __init__(self,name,age):
self.name=name
self.age=age

def sit(self):
print(self.name.title()+" is now sitting.")

def roll_over(self):
print(self.name.title()+" rolled over!")
#import_class.py:
from class_ import Dog
class Cat(Dog):
def __init__(self,name,age):
super().__init__(name,age)
def sit(self):
print(self.name.title()+" is sitting !!!")
my_cat=Cat('miaomiao',6)
my_cat.sit()
my_cat.roll_over()
#编译运行import_class.py文件后:
Miaomiao is sitting !!!
Miaomiao rolled over!

class_.py即为模块文件,而模块文件中可以存储多个类,而在一个模块中到处多个类的语法为:

1
from base_module_file_name import base_file1_name,base_file2_name,base_file3_name...

导入整个模块的语法:

1
import base_module_file_name

导入模块中的所有类的语法(不推荐使用):

1
from base_module_file_name import *

与函数导入方法基本一致,同样的,一个python文件也可以从多个模块文件中调取多个不同的类,模块内部也可以调用其他模块中已有的类,在此不再赘述。


File and exception文件与异常:

Read data from a file:

读取当前路径下文件:

举个例子哦,我们在项目文件夹下,创建一个名为lyrics的txt文件,继续在文件夹下创建lyrics_reader文件,具体内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#lyrics.txt
Midnight, you come and pick me up, no headlights
Long drive, could end in burning flames or paradise
Fade into view, oh,
It's been a while since I have even heard from you
(Heard from you)
I should just tell you to leave 'cause I
Know exactly where it leads but I
Watch it go round and round each time
----Taylor Swift <style>
#lyrics_reader.py
with open('lyrics.txt') as wyh:
print(wyh.read())
##out:
Midnight, you come and pick me up, no headlights
Long drive, could end in burning flames or paradise
Fade into view, oh,
It's been a while since I have even heard from you
(Heard from you)
I should just tell you to leave 'cause I
Know exactly where it leads but I
Watch it go round and round each time
----Taylor Swift <style>

两文件须在同一文件夹下,关键词with用于在不需要访问文件时自动将.txt文件关闭,也可以不用with,直接调用open()打开文件,但一定记得在合适的时候用close()关闭文件;wyh这个变量是自己随机取,并且其代表的是打开的这个文件,是一个对象,而不是里面的内容,所以读取内容后面用到了.read()函数。

读取规定路径下文件:

代码格式:

Linux&OS X中:

1
with open('text_files_path/filename.txt' as XXX)

Windows中:

1
with open('text_files_path\filename.txt' as XXX)

需要注意的是,window系统的写法有时候反斜杠会导致转义,所以可以在路径的单引号之前加上r,无需空格

另外路径也不可直接在属性–安全–对象名称直接复制,从别的地方复制或是手打即可,而且上网查了下,现在/ \分的也不是那么开,windows也能用/

对文件逐行读取:

1
for i(or something else) in XXX:

like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
将上面的lyrics_reader.py修改为:
with open('C:/Users/HP/Desktop/lyrics.txt') as wyh:
for line in wyh:
print(line)
###Out:
Midnight, you come and pick me up, no headlights

Long drive, could end in burning flames or paradise

Fade into view, oh,

It's been a while since I have even heard from you

(Heard from you)

I should just tell you to leave 'cause I

Know exactly where it leads but I

Watch it go round and round each time

----Taylor Swift <style>

mieye

能否用一个列表保存每一行的内容呢?这当然是可行的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
with open('pi_dights.txt') as wyh:
lines=wyh.readlines()
print(lines)
for line in lines :
print(line)
print('\n')
for line in lines :
print(line.rstrip())
###out:
['3.141592653\n', '58979323846\n', '2643383279']
3.141592653

58979323846

2643383279


3.141592653
58979323846
2643383279

readlines()函数从文件读取每一行然后存储进列表,具体用法就如上

读取文本文件,python将其中所有文本都解读为字符串,如果要使用读取的数值,需要用int()或是float()转换再使用

圆周率中包含你的生日吗?

在网上下载到圆周率前100万位的txt文件,然后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
with open('C:/Users/HP/Downloads/Compressed/《Python编程》源代码文件/chapter_10/pi_million_digits.txt') as wyh:
lines=wyh.readlines()
pi=''
for line in lines:
pi+=line.strip()
while True:
message_=input("Start or quit?")
if message_=='quit' :
break
else:
birthday=input("Please enter your birthday: \n")
if birthday in pi:
print("Your birthday appears in the first millon digits of pi !")
else:
print("That's too regretful")
###out:
Start or quit?start
Please enter your birthday:
0724
Your birthday appears in the first millon digits of pi !
Start or quit?1
Please enter your birthday:
20000724
That's too regretful
Start or quit?1
Please enter your birthday:
0926
Your birthday appears in the first millon digits of pi !
Start or quit?1
Please enter your birthday:
0218
Your birthday appears in the first millon digits of pi !
Start or quit?quit

Write data to a file:

写入空文件:

两个文件,在相同文件夹下创建programming.txt和write_message.py文件,前者为空文件,后者代码为:

1
2
with open('programming.txt','w') as wyh:
wyh.write("I love python!")

写入多行时:

需注意不能指望通过在py文件中直接换行来在.txt文件中也换行,需要加换行符\n

‘w’覆盖模式:

运行之后再去看.txt文件会发现多了一行:I love python!

另外写入只能写入字符串,所以要想将数值存储到文本文件中,需要使用str()转换

‘a’附加模式:

很简单,在原有文件基础上加上部分内容的模式,只需将’w’–>’a’即可

Exceptions:

ZeroDivisionError:

众所周知,0不能被除,如果被除会报错:ZeroDivisionError: division by zero

try-except:

0被除时,如果我不想报错,而是想打印出提示信息呢?

1
2
3
4
5
6
try:
print(5/0)
except ZeroDivisionError:
print("you can't divide by zero!")
###out:
you can't divide by zero!

此时程序不会报错,如果后面还有代码,仍会继续执行。

如果except后不接特定异常,会捕获所有异常–不推荐,这样不知道是什么异常;

一个try后可接多个except语句,捕获多种错误并处理,而且except后也可接多种异常如:

1
2
except (ValueError,ZeroDivisionError): 
print('Invalid input!')

else语句:写在except语句之后,也就是异常没有触发就可以执行else的语句

finally语句:与else语句位置相同,但是不管异常有没有处罚都要执行(我寻思那不就是直接写上去了?)

FileNotFoundError:

尝试读取一个不存在的文件,报错:FileNotFoundError: [Errno 2] No such file or directory: ‘pi_dights.txt’

这是读取文件的情况下,但是如果是write(),如果该文件不存在会自己生成一个对应的文件

Analysis text:

对文本的分析:–分析一本书有多少单词:

1
2
3
4
5
6
7
8
9
10
filename='C:/Users/HP/Desktop/11.txt'
try:
with open (filename) as wyh:
_=wyh.read()
except FileNotFoundError:
print("sorry , this file does not exist!")
else:
print("The file has about "+str(len(_.split()))+" words!")
###Out:
The file has about 29465 words!

分析多个文本:

(注意编码问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#book_read.py
def count_words(filename):
try:
with open (filename,encoding='UTF-8') as wyh:
_=wyh.read()
except FileNotFoundError:
print("sorry , this file does not exist!")
else:
print("The file has about "+str(len(_.split()))+" words!")
#words_count.py
from book_read import count_words
filenames=['11.txt','60076-0.txt','60067-0.txt']
for filename in filenames:
count_words(filename)
###oUT:
The file has about 29465 words!
The file has about 175656 words!
The file has about 92430 words!

倘若不加“encoding=’UTF-8’”可能会(我的VSCODE)报错,读取一个(11.txt)没问题,后面读取不了

报错信息:

1
UnicodeDecodeError: 'gbk' codec can't decode byte 0x9c in position 1177: illegal multibyte sequence

Storing data:

模块json可以将简单的python数据结构转储到文件中,并在文件再次运行时加载数据

使用json.dump()和json.load():

json.dump()存储数据,json.load()加载数据:

1
2
3
4
5
6
7
8
import json
_=[2,3,4,5,6,7,8,9]
with open('_.json','w') as wyh:
json.dump(_,wyh)
###已生成_.json文件,内容:[2, 3, 4, 5, 6, 7, 8, 9]
with open('_.json') as cnm:
_1=json.load(cnm)
print(_1)

以上就是基本用法

就写这些吧,后面的还有一点我自己看看就不写博客了,写点项目再挂上吧

.

.

.

.

.

.

coswindy

2019/8/9

-------------本文结束感谢您的阅读-------------
undefined