Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为整个教程整理文章格式 #13

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
6e81f33
为文中出现的代码、变量添加代码(code)格式。如:`print()`
pastgift Jun 18, 2014
db41da5
文章内容主要为配置,故主要为出现的命令、路径、文件名等添加代码(code)格式。如:`apt-get`
pastgift Jun 18, 2014
fe5fe37
为文中出现的代码、变量及路径、文件名添加代码(code)格式。如:`print()` `http://127.0.0.1`
pastgift Jun 18, 2014
f2c041a
为文中出现的代码、变量添加代码(code)格式。如:`print()`
pastgift Jun 18, 2014
5eb0a34
深入、网络:为文中出现的代码、变量添加代码(code)格式。如`print()`
pastgift Jun 19, 2014
852a71d
为文中出现的代码、变量、shell命令、Python包名添加代码(code)格式。
pastgift Jun 21, 2014
65b3860
标准库部分:为文中出现的代码、变量、命令等添加代码(code)格式。
pastgift Jun 23, 2014
8a36ecd
07.md~09.md:整体调整格式,如删除多余空行、整理代码块、修正标点符号。
pastgift Jun 23, 2014
81f8808
被解放的姜戈*.md:整体调整格式:删除多余空行、整理代码块、修正标点符号。
pastgift Jun 24, 2014
9998b51
补充*.md、深入*.md、网络*.md:整体调整格式,如删除多余空行、整理代码块、修正标点符号。
pastgift Jun 26, 2014
1059c0a
intermediate*.md:整体调整格式,如删除多余空行、整理代码块、修正标点符号。
pastgift Jul 21, 2014
033bda8
Python*.md:整体调整格式,如删除多余空行、整理代码块、修正标点符号。
pastgift Jul 22, 2014
5214874
STL*.md:整体调整格式,如删除多余空行、整理代码块、修正标点符号。
pastgift Jul 29, 2014
c322e1d
Merge pull request #2 from pastgift/generalFormatFixing
pastgift Jul 29, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 42 additions & 37 deletions content/07.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,65 @@

##函数的定义

首先,我们要定义一个函数, 以说明这个函数的功能。
首先,我们要定义一个函数,以说明这个函数的功能。

```python
def square_sum(a,b):
c = a**2 + b**2
def square_sum(a, b):
c = a ** 2 + b ** 2
return c
```

这个函数的功能是求两个数的平方和。

首先,def,这个关键字通知python:我在定义一个函数。square_sum是函数名
首先,`def`这个关键字通知`python`:我在定义一个函数。`square_sum`是函数名

括号中的a, b是函数的参数,是对函数的输入。参数可以有多个,也可以完全没有(但括号要保留)。
括号中的`a`、`b`是函数的参数,是对函数的输入。参数可以有多个,也可以完全没有(但括号要保留)。

我们已经在循环和选择中见过冒号和缩进来表示的隶属关系。

c = a**2 + b**2 # 这一句是函数内部进行的运算

```python
c = a ** 2 + b ** 2 # 这一句是函数内部进行的运算。
return c # 返回c的值,也就是输出的功能。Python的函数允许不返回值,也就是不用return。
```

return可以返回多个值,以逗号分隔。相当于返回一个tuple(定值表)。

return a,b,c # 相当于 return (a,b,c)
`return`可以返回多个值,以逗号分隔。相当于返回一个`tuple`(定值表)。


```python
return a, b, c # 相当于 return (a, b, c)
```

在Python中,当程序执行到return的时候,程序将停止执行函数内余下的语句。return并不是必须的,当没有return, 或者return后面没有返回值时,函数将自动返回None。None是Python中的一个特别的数据类型,用来表示什么都没有,相当于C中的NULL。None多用于关键字参数传递的默认值
在Python中,当程序执行到`return`的时候,程序将停止执行函数内余下的语句。`return`并不是必须的,当没有`return`,或者`return`后面没有返回值时,函数将自动返回`None`

`None`是Python中的一个特别的数据类型,用来表示什么都没有,相当于C中的NULL。`None`多用于关键字参数传递的默认值。

##函数调用和参数传递

定义过函数后,就可以在后面程序中使用这一函数
定义过函数后,就可以在后面程序中使用这一函数:

```python
print square_sum(3,4)
print square_sum(3, 4)
```
Python通过位置,知道3对应的是函数定义中的第一个参数a, 4对应第二个参数b,然后把参数传递给函数square_sum。

(Python有丰富的参数传递方式,还有关键字传递、表传递、字典传递等,基础教程将只涉及位置传递)
Python通过位置,知道`3`对应的是函数定义中的第一个参数`a`,`4`对应第二个参数`b`,然后把参数传递给函数`square_sum`。

函数经过运算,返回值25, 这个25被print打印出来。
(Python有丰富的参数传递方式,还有关键字传递、表传递、字典传递等,基础教程将只涉及位置传递。)

函数经过运算,返回值`25`,这个`25`被`print`打印出来。

我们再看下面两个例子
我们再看下面两个例子

```python
a = 1

def change_integer(a):
a = a + 1
return a

print change_integer(a)
print a

#===(Python中 "#" 后面跟的内容是注释,不执行 )
# (Python中 "#" 后面跟的内容是注释,不执行)

b = [1,2,3]
b = [1, 2, 3]

def change_list(b):
b[0] = b[0] + 1
Expand All @@ -71,34 +73,37 @@ def change_list(b):
print change_list(b)
print b
```
第一个例子,我们将一个整数变量传递给函数,函数对它进行操作,但原整数变量a不发生变化。

第二个例子,我们将一个表传递给函数,函数进行操作,原来的表b发生变化。
第一个例子,我们将一个整数变量传递给函数,函数对它进行操作,但原整数变量`a`不发生变化。

第二个例子,我们将一个表传递给函数,函数进行操作,原来的表`b`发生变化。

对于基本数据类型的变量,变量传递给函数后,函数会在内存中复制一个新的变量,从而不影响原来的变量。

对于基本数据类型的变量,变量传递给函数后,函数会在内存中复制一个新的变量,从而不影响原来的变量。(我们称此为值传递)
(我们称此为值传递)

但是对于表来说,表传递给函数的是一个指针,指针指向序列在内存中的位置,在函数中对表的操作将在原有内存中进行,从而影响原有变量。 (我们称此为指针传递)
但是对于表来说,表传递给函数的是一个指针,指针指向序列在内存中的位置,在函数中对表的操作将在原有内存中进行,从而影响原有变量。

(我们称此为指针传递)

##总结

```python
def function_name(a,b,c):
def function_name(a, b, c):
statement
return something # return不是必须的
```
return something # return不是必须的。
```

函数的目的: 提高程序的重复可用性。

return None
`return`、`None`

通过位置,传递参数。

基本数据类型的参数:值传递

表作为参数:指针传递
基本数据类型的参数:值传递。

表作为参数:指针传递。

练习:

写一个判断闰年的函数,参数为年、月、日。若是是闰年,返回True
写一个判断闰年的函数,参数为年、月、日。若是是闰年,返回`True`。
72 changes: 41 additions & 31 deletions content/08.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Python基础08 面向对象的基本概念

Python使用类(class)和对象(object),进行面向对象(object-oriented programming,简称OOP)的编程。
Python使用类class和对象object,进行面向对象(object-oriented programming,简称OOP)的编程。

面向对象的最主要目的是提高程序的重复使用性。我们这么早切入面向对象编程的原因是,Python的整个概念是基于对象的。了解OOP是进一步学习Python的关键。

Expand All @@ -12,26 +12,36 @@ Python使用类(class)和对象(object),进行面向对象(object-oriented p

面向对象就是模拟了以上人类认知过程。在Python语言,为了听起来酷,我们把上面说的“东西”称为对象(object)。

先定义鸟类
先定义鸟类:

```python
class Bird(object):
have_feather = True
way_of_reproduction = 'egg'
```
我们定义了一个类别(class),就是鸟(Bird)。在隶属于这个类比的语句块中,我们定义了两个变量,一个是有羽毛(have_feather),一个是生殖方式(way_of_reproduction),这两个变量对应我们刚才说的属性(attribute)。我们暂时先不说明括号以及其中的内容,记为问题1。

假设我养了一只小鸡,叫summer。它是个对象,且属于鸟类。使用前面定义的类:
我们定义了一个类别(class),就是鸟(`Bird`)。

在隶属于这个类比的语句块中,我们定义了两个变量,一个是有羽毛(`have_feather`),一个是生殖方式(`way_of_reproduction`),这两个变量对应我们刚才说的属性(attribute)。

我们暂时先不说明括号以及其中的内容,记为问题1。

假设我养了一只小鸡,叫`summer`。它是个对象,且属于鸟类。使用前面定义的类:

```python
summer = Bird()
print summer.way_of_reproduction
```
通过第一句创建对象,并说明summer是类别鸟中的一个对象,summer就有了鸟的类属性,对属性的引用是通过 对象.属性(object.attribute) 的形式实现的。

可怜的summer,你就是个有毛产的蛋货,好不精致。
通过第一句创建对象,并说明`summer`是类别鸟中的一个对象,`summer`就有了鸟的类属性,对属性的引用是通过 对象.属性(`object.attribute`) 的形式实现的。

可怜的`summer`,你就是个有毛产的蛋货,好不精致。

##动作

日常认知中,我们在通过属性识别类别的时候,有时根据这个东西能做什么事情来区分类别。比如说,鸟会移动。这样,鸟就和房屋的类别区分开了。这些动作会带来一定的结果,比如移动导致位置的变化。
日常认知中,我们在通过属性识别类别的时候,有时根据这个东西能做什么事情来区分类别。

比如说,鸟会移动。这样,鸟就和房屋的类别区分开了。这些动作会带来一定的结果,比如移动导致位置的变化。

这样的一些“行为”属性为方法(method)。Python中通过在类的内部定义函数,来说明方法。

Expand All @@ -40,31 +50,32 @@ class Bird(object):
have_feather = True
way_of_reproduction = 'egg'
def move(self, dx, dy):
position = [0,0]
position = [0, 0]
position[0] = position[0] + dx
position[1] = position[1] + dy
return position

summer = Bird()
print 'after move:',summer.move(5,8)
print 'after move:', summer.move(5, 8)
```
我们重新定义了鸟这个类别。鸟新增一个方法属性,就是表示移动的方法move。(我承认这个方法很傻,你可以在看过下一讲之后定义个有趣些的方法)

(它的参数中有一个self,它是为了方便我们引用对象自身。方法的第一个参数必须是self,无论是否用到。有关self的内容会在下一讲展开)
我们重新定义了鸟这个类别。鸟新增一个方法属性,就是表示移动的方法`move`。(我承认这个方法很傻,你可以在看过下一讲之后定义个有趣些的方法。)

(它的参数中有一个`self`,它是为了方便我们引用对象自身。方法的第一个参数必须是`self`,无论是否用到。有关`self`的内容会在下一讲展开)

另外两个参数,dx, dy表示在x、y两个方向移动的距离。move方法会最终返回运算过的position
另外两个参数,`dx`、`dy`表示在`x`、`y`两个方向移动的距离。`move`方法会最终返回运算过的`position`

在最后调用move方法的时候,我们只传递了dx和dy两个参数,不需要传递self参数(因为self只是为了内部使用)。
在最后调用`move`方法的时候,我们只传递了`dx`和`dy`两个参数,不需要传递`self`参数(因为`self`只是为了内部使用)。

我的summer可以跑了
我的`summer`可以跑了

##子类

类别本身还可以进一步细分成子类

比如说,鸟类可以进一步分成鸡,大雁,黄鹂。

在OOP中,我们通过继承(inheritance)来表达上述概念。
在OOP中,我们通过继承inheritance来表达上述概念。

```python
class Chicken(Bird):
Expand All @@ -77,38 +88,37 @@ class Oriole(Bird):

summer = Chicken()
print summer.have_feather
print summer.move(5,8)
print summer.move(5, 8)
```
新定义的鸡(Chicken)类的,增加了两个属性:移动方式(way_of_move),可能在KFC找到(possible_in_KFC)

在类定义时,括号里为了Bird。这说明,Chicken是属于鸟类(Bird)的一个子类,即Chicken继承自Bird。自然而然,Bird就是Chicken的父类。Chicken将享有Bird的所有属性。尽管我只声明了summer是鸡类,它通过继承享有了父类的属性(无论是变量属性have_feather还是方法属性move)
新定义的鸡(`Chicken`)类的,增加了两个属性:移动方式(`way_of_move`),可能在KFC找到(`possible_in_KFC`)。

在类定义时,括号里为了`Bird`。这说明,`Chicken`是属于鸟类(`Bird`)的一个子类,即`Chicken`继承自`Bird`。自然,`Bird`就是`Chicken`的父类。`Chicken`将享有`Bird`的所有属性。

新定义的黄鹂(Oriole)类,同样继承自鸟类。在创建一个黄鹂对象时,该对象自动拥有鸟类的属性。
尽管我只声明了`summer`是鸡类,它通过继承享有了父类的属性。(无论是变量属性`have_feather`还是方法属性`move`)


新定义的黄鹂(`Oriole`)类,同样继承自鸟类。在创建一个黄鹂对象时,该对象自动拥有鸟类的属性。

通过继承制度,我们可以减少程序中的重复信息和重复语句。如果我们分别定义两个类,而不继承自鸟类,就必须把鸟类的属性分别输入到鸡类和黄鹂类的定义中。整个过程会变得繁琐,因此,面向对象提高了程序的可重复使用性。
通过继承制度,我们可以减少程序中的重复信息和重复语句。

(回到问题1, 括号中的object,当括号中为object时,说明这个类没有父类(到头了))
如果我们分别定义两个类,而不继承自鸟类,就必须把鸟类的属性分别输入到鸡类和黄鹂类的定义中。整个过程会变得繁琐,因此,面向对象提高了程序的可重复使用性。

(回到问题1:括号中的`object`,当括号中为`object`时,说明这个类没有父类(到头了))

将各种各样的东西分类,从而了解世界从人类祖先开始,我们就在练习了这个认知过程,面向对象是符合人类思维习惯的。所谓面向过程,也就是执行完一个语句再执行下一个,更多的是机器思维。通过面向对象的编程,我们可以更方便的表达思维中的复杂想法
将各种各样的东西分类,从而了解世界从人类祖先开始,我们就在练习了这个认知过程,面向对象是符合人类思维习惯的。而所谓面向过程,也就是执行完一个语句再执行下一个,更多的是机器思维。

通过面向对象的编程,我们可以更方便的表达思维中的复杂想法。

##总结

将东西根据属性归类 ( 将object归为class )
将东西根据属性归类将object归为class

方法是一种属性,表示动作
方法是一种属性,表示动作

用继承来说明父类-子类关系。子类自动具有父类的所有属性。

self代表了根据类定义而创建的对象
`self`代表了根据类定义而创建的对象

建立对一个对象: 对象名 = 类名()
建立对一个对象:对象名 = 类名()

引用对象的属性: object.attribute
引用对象的属性:`object.attribute`
Loading