学习笔记,来源:笨方法学python
1、windows下的cmd与powershell
- 简单的说,Powershell是cmd的超集,换句话说,cmd能做的事情,Powershell都能做,但是Powershell还能额外做许多cmd不能做的活
- cmd是和powershell都可以做命令行交互,批处理和powershell脚本功能也相当。
2、在Powershell上创建一个目录并进入该目录
- 开始——运行——powershell
- 直接输入,你想要把新建目录放在哪个盘下面,我选的是d盘,然后回车就会出现PS D:\>的字样
- 直接在后面输入mkdir(新建目录)
- 会出现path[0]:的字样,然后输入d:\expy,回车,会出现path[1]:,不用管接着回车,
- 新建完毕
- 然后在PS D:\>后面输入cd expy,就进入了expy文件夹中
3、数字和数学计算
- + plus 加号
- - minus 减号
- / slash 斜杠 除法
- * asterisk 星号 乘法
- % percent 百分号 模除
- < less-than 小于号
- > greater-than 大于号
- <= less-than-equal 小于等于号
- >= greater-than-equal 大于等于号
4、变量和命名
my_age = 21 my_weight = 65 my_height = 188 print("I am %d years old ,and i am %d tall.my weight is %d " %(my_age,my_height,my_weight))
结果:
注意:
- 变量需要以字母开头
- %s , %r , %d :它们都是“格式化字符串”,
5、字符串和文本
- %r 和 %s 有什么不同?
text = ("I am %d years old." % 22) print ("I said: %s." % text) print ("I said: %r." % text)
结果:
注:%r 是调试用的, 而 %s 才是显示输出用的。
6、打印
- 格式化字符串内部嵌套使用格式化
formatter = ("%r %r %r %r") print ((formatter) % (1, 2, 3, 4)) print ((formatter) % ("one", "two", "three", "four")) print ((formatter) % (True, False, False, True)) print ((formatter) % (formatter, formatter, formatter, formatter)) print ((formatter) % ( "I had this thing.", "That you could type up right.", "But it didn't sing.", "So I said goodnight." ))
结果:
- 两种让字符串扩展到多行的方法
-
- 第一种方法是在月份之间用 \n (backslash n )隔开。 这两个字符的作用是在该位置上放入一个“新行(new line)”字符。
- 第二种方法是使用“三引号(triple-quotes)”, 也就是 """ , 你可以在一组三引号之间放入任意多行的文字
7、转义字符
8、input()
print ("How old are you?"),
age = input()
print ("How tall are you?"),
height = input()
print ("How much do you weigh?"),
weight = input()
print (("So, you're %r old, %r tall and %r heavy.") % (age, height, weight))
结果:
NOTE:在每行 print 后面加了个逗号(comma) ! 这样的话 print 就不会输出新行符而结束这一行跑到下一行去了。
input() 和 raw_input() 有什么区别?
在Python代码里 input() 方法将会改变你输入的东西, 但是这个方法存在安全问题, 请尽量避免使用它。
可以提示用户输入内容:
age = input("How old are you?"),
height = input("How tall are you?"),
weight = input("How much do you weigh?"),
print (("So, you're %r old, %r tall and %r heavy.") % (age, height, weight))
结果:
9、参数、解包、变量
- 将变量传递给脚本的方法
from sys import argv #argv 就是所谓的“参数变量(argument variable)”, 它是一个非常标准的编程术语。 script, first, second, third = argv print ("The script is called:", script) print ("Your first variable is:", first) print ("Your second variable is:", second) print ("Your third variable is:", third)
运行:
- argv和input有什么区别?
它们的不同之处在于要求用户输入的位置不同。 如果你想让用户在命令行输入你的参数, 你应该使用 argv ., 如果你
希望用户在脚本执行的过程中输入参数, 那就就要用到 raw_input() 。
10、提示与传递
from sys import argscript, user_name = argv
print ("Hi %s, I'm the %s script." % (user_name, script))
print ("I'd like to ask you a few questions.")
print ("Do you like me %s?" % user_name)
likes = input(prompt)
print ("Where do you live ,%s?" % user_name)
lives = input(prompt)
print ("What kind of computer do you have?")
computer = input(prompt)
print ("""
Alright, so you said %r about liking me.
You live in %r. Not sure where that is.
And you have a %r computer. Nice.
""" % (likes, lives, computer))
NOTE:
#三个引号 """ 可以定义多行字符串, 而 % 是字符串的格式化工具
#prompt = ('> ') #将用户提示符设置为变量 prompt , 这样我们就不需要在每次用到input 时重复输入提示用户的字符了
NOTE:python2.x与python3.x 的区别:
- python3.x 中用input(),python2.x 中用raw_input()
- python3.x 中print() 后面要加圆括号;
11、读文件
- 准备好文件
from sys import argv
script, filename = argv
txt = open(filename)
print ("Here's your file %r:" % filename)
print (txt.read())
print ("Type the filename again:")
file_again = input("> ")
txt_again = open(file_again)
print (txt_again.read())
运行:
疑问:
12、读写文件
常用命令:
close -- 关闭文件。 跟你编辑器的 文件->保存.. 一个意思。
read -- 读取文件内容。 你可以把结果赋给一个变量。
readline -- 读取文本文件中的一行。
truncate -- 清空文件, 请谨慎使用该命令。
write('stuff') -- 将stuff写入文件
示例:
"""
首先强控源文件内容
往文件中写入醒的内容
"""
from sys import argv
script, filename = argv #需要在命令行输入参数
print ("We're going to erase %r." % filename)
print ("If you don't want that, hit CTRL-C (^C).")
print ("If you do want that, hit RETURN.")
input("?")
print ("Opening the file...")
target = open(filename, 'w') #创建变量,赋值,以可写的方式打开文件
print ("Truncating the file. Goodbye!")
target.truncate() #调用truncate函数清空文件
print ("Now I'm going to ask you for three lines.")
line1 = input("line 1: ") #从键盘输入三行文本
line2 = input("line 2: ")
line3 = input("line 3: ")
print ("I'm going to write these to the file.")
target.write(line1) #将输入的文本写入文件
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")
print ("And finally, we close it.")
target.close() #关闭文件
在powershell中运行:
NOTE:
- open(filename):无修饰符时,是以“r”(只读)模式打开文件的(默认);
- 修饰符:
- a:追加模式
- r:只读模式
- w:以写模式
- a+:读写模式
- r+:读写模式
- w+:读写模式
13、更多文件操作(文件拷贝)
将一个文件中的内容拷贝到另外一个文件中 。
from sys import argv
from os.path import exists
script, from_file, to_file = argv #一定注意传参数的顺序
print ("Copying from %s to %s" % (from_file, to_file))
# we could do these two on one line, how?
in_file = open(from_file)
indata = in_file.read()
print ("The input file is %d bytes long" % len(indata))
print ("Does the output file exist? %r" % exists(to_file))
print ("Ready, hit RETURN to continue, CTRL-C to abort.")
input(">>>")
out_file = open(to_file, 'w')
out_file.write(indata)
print ("Alright, all done.")
out_file.close()
in_file.close()
运行:
NOTE:一定注意传参数的顺序!!!!!!!!
14、命名、变量、代码、函数(function)
- 函数可以做三样事情:
1. 它们给代码片段命名, 就跟“变量”给字符串和数字命名一样。
2. 它们可以接受参数, 就跟脚本接受 argv 一样。
3. 通过使用 #1 和 #2, 它们可以创建“微型脚本”或者“小命令”。
#把函数理解成“迷你脚本”
# this one is like your scripts with argv
def print_two(*args):
arg1, arg2 = args #将参数解包 ,和下面的三个函数不一样地方
print ("arg1: %r, arg2: %r" % (arg1, arg2))
# ok, that *args is actually pointless, we can just do this
def print_two_again(arg1, arg2):
print ("arg1: %r, arg2: %r" % (arg1, arg2))
# this just takes one argument
def print_one(arg1):
print ("arg1: %r" % arg1)
# this one takes no arguments
def print_none():
print ("I got nothin'.")
print_two("Zed","Shaw")
print_two_again("Zed","Shaw")
print_one("First!")
print_none()
运行结果:
- 函数里边的变量和脚本里边的变量之间是没有关系的 。
def cheese_and_crackers(cheese_count, boxes_of_crackers):
print ("You have %d cheeses!" % cheese_count)
print ("You have %d boxes of crackers!" % boxes_of_crackers)
print ("Man that's enough for a party!")
print ("Get a blanket.\n")
print ("We can just give the function numbers directly:")
cheese_and_crackers(20, 30)
print ("OR, we can use variables from our script:")
amount_of_cheese = 10
amount_of_crackers = 50
cheese_and_crackers(amount_of_cheese, amount_of_crackers)
print ("We can even do math inside too:")
cheese_and_crackers(10 + 20, 5 + 6)
print ("And we can combine the two, variables and math:")
cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers + 1000)
运行结果:
NOTE: 理论上有无数种方法去调用一个函数。 看看你对函数、 变量、 用户输入有多少想象力和创造力。
15、函数和文件
好好理解吧!!!!
from sys import argv
script, input_file = argv #脚本参数解包
def print_all(f): #定义函数
print (f.read()) #打印
def rewind(f): #定义函数
f.seek(0)
def print_a_line(line_count, f): #定义函数
print (line_count, f.readline())
current_file = open(input_file) #定义变量
print ("First let's print the whole file:\n")
print_all(current_file) #调用函数
print ("Now let's rewind, kind of like a tape.")
rewind(current_file) #调用函数
print ("Let's print three lines:")
current_line = 1 #定义变量
print_a_line(current_line, current_file) #调用函数
current_line = current_line + 1
print_a_line(current_line, current_file) #调用函数
current_line = current_line + 1
print_a_line(current_line, current_file) #调用函数
运行结果:
问题:
- print_all 中的 f 是什么 ?
- 为什么 seek(0) 方法没有把 current_line 的值修改为0?
16、函数的返回值
def add(a, b):
print ("ADDING %d + %d" % (a, b))
return (a + b)
def subtract(a, b):
print ("SUBTRACTING %d - %d" % (a, b))
return (a - b)
def multiply(a, b):
print ("MULTIPLYING %d * %d" % (a, b))
return (a * b)
def divide(a, b):
print ("DIVIDING %d / %d" % (a, b))
return (a / b)
print ("Let's do some math with just functions!")
age = add(30, 5)
height = subtract(78, 4)
weight = multiply(90, 2)
iq = divide(100, 2)
print ("Age: %d, Height: %d, Weight: %d, IQ: %d" % (age, height, weight, iq))
# A puzzle for the extra credit, type it in anyway.
print ("Here is a puzzle.")
what = add(age, subtract(height, multiply(weight, divide(iq, 2))))
print ("That becomes: ", what, "Can you do it by hand?")
运行结果:
17、练习
print ("Let's practice everything.") #打印
print ('You\'d need to know \'bout escapes with \\ that do \n newlines and \t tabs.')
poem = """
\tThe lovely world
with logic so firmly planted
cannot discern \n the needs of love
nor comprehend passion from intuition
and requires an explanation
\n\t\twhere there is none.
"""
print ("--------------")
print (poem)
print ("--------------")
five = (10 - 2 + 3 - 6)
print ("This should be five: %s" % five)
def secret_formula(started): #定义secret_formula函数,函数只有一个形参:started
jelly_beans = started * 500
jars = jelly_beans / 1000
crates = jars / 100
return jelly_beans, jars, crates
start_point = 10000
(beans, jars, crates) = secret_formula(start_point) #调用函数,但是三个变量为什么放在一行。返回的三个结果分别赋给三个变量。
print ("With a starting point of: %d" % start_point)
print ("We'd have %d beans, %d jars, and %d crates." % (beans, jars, crates))
start_point = start_point / 10
print ("We can also do that this way:")
print ("We'd have %d beans, %d jars, and %d crates." % secret_formula(start_point))
结果:
18、逻辑术语
and 与
or 或
not 非
!= (not equal) 不等于
== (equal) 等于
>= (greater-than-equal) 大于等于
<= (less-than-equal) 小于等于
True 真
False 假
19、布尔表达式
布尔逻辑表达式(boolean logic expression)
20、if-else语句
21、if语句嵌套
print ("You enter a dark room with two doors. Do you go through door #1 or door #2?")
door = input(">>> ")
if door == "1":
print ("There's a giant bear here eating a cheese cake. What do you do?")
print ("1. Take the cake.")
print ("2. Scream at the bear.")
bear = input("> ")
if bear == "1":
print ("The bear eats your face off. Good job!")
elif bear == "2":
print ("The bear eats your legs off. Good job!")
else:
print ("Well, doing %s is probably better. Bear runs away." % bear)
elif door == "2":
print ("You stare into the endless abyss at Cthulhu's retina.")
print ("1. Blueberries.")
print ("2. Yellow jacket clothespins.")
print ("3. Understanding revolvers yelling melodies.")
insanity = input("> ")
if insanity == "1" or insanity == "2":
print ("Your body survives powered by a mind of jello. Good job!")
else:
print ("The insanity rots your eyes into a pool of muck. Good job!")
else:
print ("You stumble around and fall on a knife and die. Good job!")
22、循环和列表
- for 循环
#创建三个列表
the_count = [1, 2, 3, 4, 5]
fruits = ['apples', 'oranges', 'pears', 'apricots']
change = [1, 'pennies', 2, 'dimes', 3, 'quarters']
# this first kind of for-loop goes through a list
for number in the_count:
print ("This is count %d" % number)
# same as above
for fruit in fruits:
print ("A fruit of type: %s" % fruit)
# also we can go through mixed lists too
# notice we have to use %r since we don't know what's in it
for i in change:
print ("I got %r" % i)
# we can also build lists, first start with an empty one
elements = []
# then use the range function to do 0 to 5 counts
for i in range(0, 6):
print ("Adding %d to the list." % i)
# append is a function that lists understand
elements.append(i)
# now we can print them out too
for i in elements:
print ("Element was: %d" % i)
结果:
NOTE:
- 当一个列表中元素类型混杂或者未知,可以用%r 获取:
- 在for循环开始的时候, 就会定义“”i“”这个变量, 并初始化。
- range() 函数循环的次数不包括最后一个。
- 列表和数组不是同一种东西吗?
- 依赖于语言和实现方式。 在经典设计角度, 由于数组列表的实现方式不同, 数组列表是非常不同的。 在Ruby中程序员
称之为数组。 在Python中,他们称之为列表。 因为现在是Python调用它们, 所以我们就称呼它为列表。
- 依赖于语言和实现方式。 在经典设计角度, 由于数组列表的实现方式不同, 数组列表是非常不同的。 在Ruby中程序员
- while 循环((while-loop))
i = 0
numbers = []
while i < 6:
print ("At the top i is %d" % i)
numbers.append(i)
i = i + 1
print ("Numbers now: ", numbers)
print ("At the bottom i is %d" % i)
print ("The numbers: ")
for num in numbers:
print (num)
结果
NOTE:
- for 循环和while循环有什么区别 :
for 循环只能对某种事物的集合做循环, 而while可以进行任何种类的循环。 但是, while循环很容易出错, 大部分情况
for循环也是一个很好的选择。
23、访问列表元素
24、分支和函数
from sys import exit def gold_room(): print ("This room is full of gold. How much do you take?") choice = input("> ") if "0" in choice or "1" in choice: how_much = int(choice) else: dead("Man, learn to type a number.") if how_much < 50: print ("Nice, you're not greedy, you win!") exit(0) else: dead("You greedy bastard!") def bear_room(): print ("There is a bear here.") print ("The bear has a bunch of honey.") print ("The fat bear is in front of another door.") print ("How are you going to move the bear?") bear_moved = False while True: choice = input("> ") if choice == "take honey": dead("The bear looks at you then slaps your face off.") elif choice == "taunt bear" and not bear_moved: print ("The bear has moved from the door. You can go through it now.") bear_moved = True elif choice == "taunt bear" and bear_moved: dead("The bear gets pissed off and chews your leg off.") elif choice == "open door" and bear_moved: gold_room() else: print ("I got no idea what that means.") def cthulhu_room(): print ("Here you see the great evil Cthulhu.") print ("He, it, whatever stares at you and you go insane.") print ("Do you flee for your life or eat your head?") choice = input("> ") if "flee" in choice: start() elif "head" in choice: dead("Well that was tasty!") else: cthulhu_room() def dead(why): print (why, "Good job!") exit(0) def start(): print ("You are in a dark room.") print ("There is a door to your right and left.") print ("Which one do you take?") choice = input("> ") if choice == "left": bear_room() elif choice == "right": cthulhu_room() else: dead("You stumble around the room until you starve.") start()
结果
问题:
exit() 是干什么的 ?
25、Python符号和关键字
- 关键字
KEYWORD | DESCRIPTION | EXAMPLE |
and | 逻辑与 | True and False == False |
as | with-as 语句的一部分 | with X as Y: pass |
assert | 声明 | assert False, "Error!" |
break | 停止整个循环 | while True: break |
class | 定义一个类 | class Person(object) |
continue | 停止这一次循环, 但继续下一次循环 | while True: continuev |
def | 定义一个函数 | def X(): pass |
del | 从字典中删除 | del X[Y] |
elif | Else if 条件 | if: X; elif: Y; else: J |
else | Else 条件 | if: X; elif: Y; else: J |
except | 如果捕获异常, 执行该代码块 | except ValueError, e: print e |
exec | 将字符串作为Python代码执行 | exec 'print "hello"' |
finally | 不管是否有异常, finally代码块都执行 | finally: pass |
for | for循环 | for X in Y: pass |
from | 从某一模块中引入特定部分 | import X from Y |
global | 定义一个全局变量 | global X |
if | If 条件 | if: X; elif: Y; else: J |
import | 引入一个模块到当前模块 | import os |
in | for循环的一部分/ 测试 X in Y . | for X in Y: pass / 1 in [1] == True |
is | 类似 == , 判断相等 | 1 is 1 == True |
lambda | 创建一个无名函数 | s = lambda y: y ** y; s(3) |
not | 逻辑非 | not True == False |
or | 逻辑或 | True or False == True |
pass | 该代码块为空 | def empty(): pass |
打印一个字符串 | print 'this string' | |
raise | 代码出错时, 抛出一个异常 | raise ValueError("No") |
return | 退出函数并返回一个返回值 | def X(): return Y |
try | 尝试代签代码块, 有异常则进入except代码块 | try: pass |
while | While循环 | while X: pass |
with | 一个变量的别名 | with X as Y: pass |
yield | 暂停, 返回给调用者 | def X(): yield Y; X().next() |
- 数据类型
TYPE | DESCRIPTION | EXAMPLE |
True | True 布尔值. | True or False == True |
False | False 布尔值. | False and True == False |
None | 表示 "nothing" 或者"no value". | x = None |
strings | 字符串, 储存文本信息 | x = "hello" |
numbers | 储存整数 | i = 100 |
floats | 储存小数 | i = 10.389 |
lists | 储存某种东西的列表 | j = [1,2,3,4] |
dicts | 储存某些东西的键值对 | e = {'x': 1, 'y': 2} |
- 字符串转义序列
ESCAPE | DESCRIPTION |
\\ | 斜线 |
\' | 单引号 |
\" | 双引号 |
\a | Bell |
\b | 退格 |
\f | Formfeed |
\n | 换行 |
\r | Carriage |
\t | Tab键 |
\v | 垂直的tab |
- 字符串格式化
ESCAPE | DESCRIPTION | EXAMPLE |
%d | 格式化整数 (不包含浮点数). | "%d" % 45 == '45' |
%i | 与%d相同 | "%i" % 45 == '45' |
%o | 8进制数字 | "%o" % 1000 == '1750' |
%u | 负数 | "%u" % -1000 == '-1000' |
%x | 小写的十六进制数字 | "%x" % 1000 == '3e8' |
%X | 大写的十六进制数字 | "%X" % 1000 == '3E8' |
%e | 小写 'e'的指数标记 | "%e" % 1000 == '1.000000e+03' |
%E | 大写 'e'的指数标记 | "%E" % 1000 == '1.000000E+03' |
%f | 浮点数 | "%f" % 10.34 == '10.340000' |
%F | 与%f相同 | "%F" % 10.34 == '10.340000' |
%g | %f 或者 %e中较短的一个 | "%g" % 10.34 == '10.34' |
%G | %F 或者 %E中较短的一个 | "%G" % 10.34 == '10.34' |
%c | 字符格式化 | "%c" % 34 == '"' |
%r | 类型格式化 | "%r" % int == "<type 'int'>" |
%s | 字符串格式 | "%s there" % 'hi' == 'hi there' |
%% | 表示百分号% | "%g%%" % 10.34 == '10.34%' |
- 操作符
OPERATOR | DESCRIPTION | EXAMPLE |
+ | 加 | 2 + 4 == 6 |
- | 减 | 2 - 4 == -2 |
* | 乘 | 2 * 4 == 8 |
** | 幂乘 | 2 ** 4 == 16 |
/ | 除 | 2 / 4.0 == 0.5 |
// | 整除, 得到除法的商。 | 2 // 4.0 == 0.0 |
% | 模除, 返回除法的余数。 | 2 % 4 == 2 |
< | 小于 | 4 < 4 == False |
> | 大于 | 4 > 4 == False |
<= | 小于等于 | 4 <= 4 == True |
>= | 大于等于 | 4 >= 4 == True |
== | 等于, 比较操作对象是否相等。 | 4 == 5 == False |
!= | 不等于 | 4 != 5 == True |
<> | 不等于 | 4 <> 5 == True |
( ) | 括号 | len('hi') == 2 |
[ ] | 列表括号 | [1,3,4] |
{ } | 字典括号 | {'x': 5, 'y': 10} |
@ | 装饰符 | @classmethod |
, | 逗号 | range(0, 10) |
: | 冒号 | def X(): |
. | Dot | self.x = 10 |
= | 赋值等于 | x = 10 |
; | 分号 | print "hi"; print "there" |
+= | 加等于 | x = 1; x += 2 |
-= | 减等于 | x = 1; x -= 2 |
*= | 乘等于 | x = 1; x *= 2 |
/= | 除等于 | x = 1; x /= 2 |
//= | 整除等于 | x = 1; x //= 2 |
%= | 模除等于 | x = 1; x %= 2 |
**= | 幂乘等于 | x = 1; x **= 2 |
26、字典(dictionary)
- dict:可以通过任何东西找到元素, 不只是数字。{ } 无序
- list: 只能通过数字来获取列表中的元素 . [ ] 有序
27、模块、类和对象
Python是一门面向对象编程语言,有叫做类的概念。
- 模块就像字典
在Python中有一套通用的模式:
- 有一个key = value 模式的容器;
- 通过key 从容器中获取数据;
在字典中, key是一个字符串, 写法为 [key] ,在模块中, key是一个标识符, 写法为 .key , 在其余的地方, 他们几乎是一样
的。
- 类就像模块
可以认为一个模块就是一个可以存放Python代码的特殊字典, 这样你就可以通过 . 操作符访问它。
Python还有一个另外的结构提供相似的功能, 就是类(class) 。类的作用是组织一系列的函数和数据并将它们放在一个容器里,
这样你可以通过 . 操作符访问到它们。
- 对象就像导入
-
- 如果一个类就像一个迷你模块, 那么类也会有一个类似 import 的概念, 这个概念被称为实例化,
- 当一个类被实例化, 你就得到一个类的对象。
- 实例化类的方法就是像调用函数一样调用这个类。
问题:为什么我在类里创建 __init__ 或其他函数的时候需要使用 self ?
如果你不使用 self , 像这种代码 cheese = 'Frank' 就是不明确的. 代码并不清楚指的是实例的 cheese 属性, 还是一
个叫做 cheese d的全局变量。 如果使用 self.cheese='Frank' 代码就会十分清楚你指的就是实例中的属
性 self.cheese .
28、对象、类、以及从属关系
- “类(class)”和“对象(object)”的区别 :
- class 和 object 并没有真正的不同,
- 它们其实是同样的东西, 只是在不同的时间名字不同罢了。
29、基本的面向对象的分析和设计
30、继承和包含
30.1继承
继承是用来描述一个类从它的父类那里获得大部分甚至全部父类的功能。
父子类之间有3中交互方法:
1. 子类的方法隐性继承父类方法
2. 子类重写父类的方法
3. 对子类的操作改变父类
隐性继承:
在父类中定义了方法, 而在子类中没有 ;
class Parent(object): def implicit(self): print ("PARENT implicit()") class Child(Parent): pass dad = Parent() son = Child() dad.implicit() son.implicit()
结果:
在 class Child 下使用 pass 的目的是告诉Python, 在这里你想要一个空白的块。 这里创建了一个叫做 Child 的类,
但是没有在这个类中定义任何性的方法。 它将从类 Parent 继承获得所有的方法。
如果你在基类(i.e., Parent )中定义了一个方法, 那么所有的子类(i.e., Child ) 都可以自动的获得这个功能。
重写方法:
关于有些方法是隐式调用的问题原因在于有时候你想让子类有不同的表现。 这时你想重写子类中的方法且有效的覆盖父类中
的方法。 要做到这一点, 你只需要在子类中定义一个同名的方法就行。
class Parent(object): def override(self): print("PARENT override()") class Child(Parent): def override(self): print("CHILD override()") dad = Parent() son = Child() dad.override() son.override()
结果:
之前或之后改变父类
class Parent(object): def altered(self): print("PARENT altered()") class Child(Parent): def altered(self): print("CHILD, BEFORE PARENT altered()") super(Child, self).altered() print("CHILD, AFTER PARENT altered()") dad = Parent() #实例化 son = Child() dad.altered() #调用 son.altered()
结果:
三种组合使用
#定义子类 class Child(Parent): def override(self): print("CHILD override()") def altered(self): print("CHILD, BEFORE PARENT altered()") super(Child, self).altered() print("CHILD, AFTER PARENT altered()") #实例化 dad = Parent() son = Child() #调用 dad.implicit() son.implicit() dad.override() son.override() dad.altered() #PARENT altered() son.altered() #CHILD, BEFORE PARENT altered() #PARENT altered() #CHILD, AFTER PARENT altered()
结果:
30.2 包含
class Other(object): def override(self): print("OTHER override()") def implicit(self): print("OTHER implicit()") def altered(self): print("OTHER altered()") class Child(object): def __init__(self): self.other = Other() def implicit(self): self.other.implicit() def override(self): print("CHILD override()") def altered(self): print("CHILD, BEFORE OTHER altered()") self.other.altered() print("CHILD, AFTER OTHER altered()") son = Child() son.implicit() son.override() son.altered()
总结:继承与包含的问题可以归结为试图解决可重复使用代码的问题。 你不想在你的软件中有重复的代码, 因为这不是高效的干净的代码。 继承通过创建一种机制, 让你在基类中有隐含的功能来解决这个问题。 而包含则是通过给你的模块和函数可以在其他类别被调用来解决这个问题。