Python—对象类别,创建对象,面向对象
2018-03-10 16:27
344 查看
1. 函数
我们在编程过程中,总是会遇到一些相似的,重复的代码段,而重复的代码段是一个程序员在编程的时候尽量避免的,所以我们可以将重复的代码定义为一个函数来精简你的代码,从而函提高应用的模块性和代码的重复利用率。你可以定义一个由自己想要功能的函数,以下是简单的规则:
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def f(a,b) f() #a和b都是默认值 f(1) #a为0,b为默认值 def f(*args): total =0 for val in args: total += val return total mylist = [1,3,,4,10] print(f(*mylist)#如果不加*,就会将mylist当做一个元素传入函数,会是数值和字符串的运算。 注意代码块后面的函数将会覆盖前面的与其相同名字的函数
作用域 - LEGB:
局部作用域–>嵌套作用域(下级可以使用上级的值)–>全局作用域–>内置作用域,值的搜索范围是从内而外的,这个优先顺序同样也适用于变量的使用。
a = 100#全局a def f() global a#读取去全局的a a = 200#若果全局没有a,则定义全局a b = 'hello' def g(): nonlocal(b)#读取上级嵌套非全局a b = 'good' 迪米特法则:最少知道原则,尽量减少全局变量的使用。
在调用内存时,之前的代码会保存现场在栈再去调用函数,调用函数之后才会恢复现场
函数也可以直接或间接调用自己,称为递归调用
#函数的递归调用 def gcd 4000 (x,y): if x > y: return gcd(y,x) elif y % x == 0: return x else: return gcd( y % x,x) if __name__ == '__main__': print(gcd(21,49))
收敛条件:让递归在有限的次数完成或者进行回溯
2.模块
常见内置模块主要有random、math、time、os等等调用模块主要通过from、import和as
一个模块尽量放与其相关的函数
一个模块中的函数可以被另一个模块调用,需要在模块后面加
if _ name _ == ‘main‘:否则另一个模块执行被调用模块中的变量
3.内存管理
内存简单分为:栈,堆,静态区引用:对象包含字符串、数值、列表等等,保存在堆空间,并将地址映射到栈中,而变量就是引用栈中对象保存在堆空间的地址,从而调用对象。
值得注意的是如果使用list1 = [0]*10的形式,那么list1只是将栈中[0]的引用地址复制了十份,在对[o]进行添加元素时只会得到一个list1。
通过调用id()函数可以看到对象在内存中的位置,调用sys.getsizeof()函数可以查看对象占用了多少空间
list1 = [0]*10 list2 = list1 ilst1和list2保存在栈中而[0]*10保存在堆空间中 f = list(range(10)) #f申请一块内存 print(list{x for x in range(10) #如果没有使用上面申请的空间,python将会将这个对象当做垃圾回收,如果不这样做内存空间将会泄漏,会导致程序闪退。 import sys list1 = [0]*10 list2 = list1 list3 = list2 print(sys.getrefcount(list1))#显示对象的引用计数,实际值比显示值小1
4.对象类别
无论是在计算机环境还是显示生活中,我们可以把世界认为是由对象构成的,在现实生活中无论动物、植物、微生物或是其他的类别,其中每一个单体都可以认为是一个对象。在计算机环境中也是一样,对象组成了计算机环境。其中主要分为以下几类:4.1字符串
字符串是Python实际应用中非常常见的一种对象类型,一般字符串是用‘’或者“”来创建,不过字符串的引号使用是不能混搭的。如:
print("i want to learn 'Python',and you?")#单引号和双引号必须分别对应
字符串的运算方式如下表:
a = ‘hello’
b = ‘world’
header 1 | header 2 | header 1 |
---|---|---|
+ | 字符串连接 | print(a +b) ‘hellohello’ |
* | 重复输出字符串 | a *2 ‘hellohello’ |
[] | 通过索引获取字符串中字符 | a[1] e |
[:] | 获取字符串中的一部分 | a[1:4] ’ell’ |
in | 成员运算符-如果字符串中包含给定的字符串返回 True | ‘h’ in a True |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True | “M” not in a True |
4.2列表
定义列表主要有以下两种方法:1. 列表生成式
mylist = [x**2 for x in range(1,10)] #用列表的生成表达式语法创建列表容器 #用这种语法创建列表之后元素已经准备就绪,所以需要耗费较多的内存空间
列表生成器
f = (x ** x for x in range(1,10)) print(f) for val in f: print(val) 列表生成器,这里得到的不是一个列表,通过生成器可以获取到数据,它不占用额外的空间存储数据,每次需要数据的时候就通过生成器获取数据,当然这需要额外花费时间。 #斐波拉切数列 def fib(n): a,b = 0,1 for _ in range(n) a,b = b,a+b yield a #yield表示将函数变成生成器 for val in fib(20): print(val) 结果如下: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
添加和插入对象:
f.append(11)
f.insert(0,2)
mylist = mylist + [20,87]
删除列表中的对象:
del f() f.index(50,2,5)#查找元素位置,括号是闭区间,如果这里的index值大于len(f),将在列表最后插入对象 f.pop()#找到列表中的值,并将它他列表中删除,默认是最后一个 f.remove()#表示移除一个元素 f.clear()#表示清理所有元素
访问列表:
miylist[0]、mylist()
切片:
[a:b:c]#a代表从多少位开始,b代表从多少位结束,c代表步长
排序:
mylist.sort() f1 = f[::-1]#对列表反转 f.reverse#反转f,将会改变f f1 = reversed(f)#不会改变f的反转将会改变mylist列表 mylist1 = mylist.sorted(reserve = True) #按首字母排序,默认是升序,降序可以通过reverse,新建一个容器来装纳新的数值顺序
4.3元组
Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
#选出一串数字的最大值和第二大的值 def second_max(x): (m1,m2) = (x[0],x[1]) if x[0] > x[1] else (x[1],x[0]) for index in range(2,len(x)): if x[index] > m1: m2 = m1 m1 = x[index] elif x[index] > m2: m2 = x[index] return m1,m2 #元组 if __name__ == '__main__': print(second_max([92,32,21,100,22]))
元组与列表最大的区别在于:元组中的对象不能被更改,但我们可以使用del语句来删除整个元组。另外,元组的创建时间比列表要短,
4.4集合
相较于列表和元组是一种无顺序的的容器,形如:set1 = {1,2,4,5,6,2,3}集合不允许出现相同的值,会自动删除多余的相同值
集合不支持下标运算
set1 = {1,2,4,5,6,2,3} set1.add(9) print(set1) set2 = {2,4,6,7,8} print(f2) set3 = set1 & set2求交集 print(set3) set3 = set1 - set2 print(set3) set3 = set1 | set2#求并集 print(set3)
运行结果:
{1, 2, 3, 4, 5, 6, 9} {2, 4, 6, 7, 8} {2, 4, 6} {1, 3, 5, 9} {1, 2, 3, 4, 5, 6, 7, 8, 9}
4.5字典
字典是另一种可变容器模型,且可存储任意类型对象(列表,元组,集合)。字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
dic = {key1 : value1, key2 : value2 }
字典有以下特征:
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
在访问字典中的值时:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; print "dict['Name']: ", dict['Name']; print "dict['Age']: ", dict['Age'];
也可以对字典中的对象进行删除和修改操作:
dict = {'name':'xiangxianzhang','age':22,'class':'Python'} dict['age'] = 23#将age键的值修改为23 del dict['age']#删除键是age的对象 print(dict)
结果显示:
{'name': 'xiangxianzhang', 'age': 23, 'class': 'Python'} {'name': 'xiangxianzhang', 'class': 'Python'}
字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的,但键不行。
两个重要的点需要记住:
不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住。
键必须不可变,所以可以用数字,字符串或元组充当,所以不能用列表来充当键。
最后举一个列子:
dictionary = {} flag = 'a' pape = 'a' off = 'a' while flag == 'a' or cefc 'c': flag = input("添加或查找单词 ?(a/c)") if flag == "a" : # 选择添加单词 word = input("输入单词(key):") defintion = input("输入定义值(value):") dictionary[str(word)] = str(defintion) # 添加到字典 print("添加成功!") pape = input("您是否要查找字典?(a/0)") if pape == 'a': #选择查找字典 print(dictionary) else : continue elif flag == 'c': check_word = input("要查找的单词:") # 检索 for key in sorted(dictionary.keys()): # yes if str(check_word) == key: print("该单词存在! " ,key, dictionary[key]) break else: # no off = 'b' print("抱歉,该值不存在!") else: # 停止 print("error type") break
结果将显示为:
输入单词(key):my_name 输入定义值(value):xiangxianzhang 添加成功! 您是否要查找字典?(a/0)0 添加或查找单词 ?(a/c)c 要查找的单词:my_name 该单词存在! my_name xiangxianzhang 添加或查找单词 ?(a/c)
5.面向对象
在实际开发应用中,我们不可能把每个代码指令都发给对象来执行,因为那样做非常浪费时间和内存,在以前的软件行业中这都是一个无法避免的问题,直到面向对象这个编程思想的出现。通常来说面向对象的实际操作流程主要分为三步;
定义一个类,给对象绑定属性。类是对象的蓝图和模板,有了类就可以创建对象,定义类需要做两件事:分析其数据抽象和行为抽象
数据抽象————抽象数据共同的静态特征(找名词)——属性
行为抽象————抽取对象共同的动态特征(找动词)——方法
定义类的关键字——class——类名(每个单词首字母大写)。
class Student(object): #构造方法 --construtor #调用该方法的时候,不是直接使用方法的名字而是使用类的名字 def __init__(self, name , age): #给对象绑定属性,第一步 self.name = name self.age = age #我们定义一个方法就代表了对象可以接受这个消息 #对象方法的第一个参数同意写成self #它代表了接收消息的对象 def study(self,course): print('%s正在学习%s' % (self.name,course)) def watch_av(self): if self.age >= 18: print('%s正在观看爱情动作片' % self.name) else: print('%s,我们推荐你看喜洋洋' % self.name) #调用构造方法创建学生对象,第二步 #实际上调用的是构造方法 def main(): stu1 = Student('xxz',22) stu1.study('python') #第三步,给对象发消息 #通过给对象发消息,让对象完成某些工作就可以实现某些工作 #解决任何问题都是通过让对象去做事情 stu2 = Student('sjy',15) stu2.age = 22 stu2.watch_av() if __name__ == '__main__': main()
运行结果:
xxz正在学习python sjy正在观看爱情动作片
#用面向对象的方法来编写一个计时器 import time class Clock(object): def __init__(self,hour=0,min=0,sec=0): self._hour = hour self._min = min self._sec = sec def min(self): self._sec -= 1 if self._sec == 60: self._sec = 0 self._min += 1 if self._min == 60: self._min = 0 self._hour += 1 if self._hour == 24: self._hour = 0 #下面的方法可以获得对象的字符串表达式 #当我们用print打印对象时会自动调用该方法 def __str__(self): return '%02d:%02d:%02d' % (self._hour,self._min,self._sec) def main(): localtime = time.localtime(time.time())#获取系统时间 clock = Clock(localtime[3],localtime[4],localtime[5]) while True: print(clock) sleep(1) clock.run() if __name__ == '__main__': main()
运行结果如下:
我们定义一个类实际上是吧数据和操作数据的函数绑定到一起,形成一个逻辑上的整体,这个整体就叫对象,而且将来任何时候想使用这个对象时直接复用这个类就可以了。
实践出真知,理论知识需要与实际情况相结合,接下来我举几个例子来加深对面向对象这种思想的理解。
6.练习
1.有十步台阶,一个小孩一次最多走三步台阶,问他有多少种走法?def sum_1_to_100(n): if n == 1: return 1 else: return n + sum_1_to_100(n-1) def walk(n): ''' :param n: 走几步台阶 :return: 有多少种走法 ''' if n < 0: return 0 elif n == 0: return 1 return walk(n-1) + walk(n-2) +walk(n-3) if __name__ == '__main__': print(walk(10))
2.机选双色球,人选注数
from random import randint def seletcd_ball(): sum_balls = [] red_balls = [x for x in range(1,34)] for _ in range(6): seletcd_red_ball = red_balls[randint(0,len(red_balls)-1)] sum_balls.append(seletcd_red_ball) red_balls.remove(seletcd_red_ball) sum_balls.sort() blue_ball = randint(1,16) sum_balls.append(blue_ball) return sum_balls def foo(balls): for ball in balls: print('%02d' % ball,end=' ') print() def mains(): n = int(input('下多少注:')) for _ in range(n): foo(seletcd_ball()) if __name__ == '__main__': mains()
3.设计一个显示炸弹倒计时的表
import time from time import sleep class Clock(object): def __init__(self,hour = 0,min = 0,sec = 0):#类下面的函数上下隔一行 self._hour = hour self._min = min self._sec = sec def run(self): self._sec -= 1 if self._sec < 0: self._min -= 1 self._sec = 59 if self._min < 0: self._hour -= 1 self._min = 59 if self._hour < 0: pass def __str__(self): return '%02d:%02d:%02d' % (self._hour, self._min, self._sec) def main(): clock = Clock(0, 1, 1) while True: print(clock) sleep(0.00001) clock.run() if 0==clock._hour == clock._min == clock._sec: print('BOOM SHAKALAKA ') break if __name__ == '__main__': main()
4.在坐标轴上标出两个点,有面向对象的方法求出两点的距离,表达a点移动到b点,表达a点移动多少距离后的点?
from math import sqrt class Point(object): def __init__(self,x = 0,y = 0): self._x = x self._y = y def distance(self,x1,y1): return sqrt(((x1 - self._x)**2 + (y1 - self._y)**2)) def to_second_point(self,x ,y ): self._x = x self._y = y def move_distance(self,dx,dy): self._x += dx self._y += dy def __str__(self): return '(%s, %s)' % (str(self._x), str(self._y)) def main(): p1 = Point(3,2) p2 = Point() print(p1.distance(9,6)) p1.to_second_point(9,6) print(p1) p1.move_distance(1,2) print(p1) if __name__ == '__main__': main()
相关文章推荐
- python面向对象中的类
- 【廖雪峰Python习题集】面向对象高级编程
- Python的面向对象之class初览
- Python的面向对象之class二看
- 面向对象高级编程——Python学习笔记08
- python 面向对象开发例子
- python3 面向对象__类的内置属性与方法的实例代码
- Python中的对象行为与特殊方法(一)对象的创建与销毁
- python学习笔记——6_面向对象
- Python 面向对象进阶
- python 2.7 : 面向对象高级编程
- JavaScript面向对象程序设计创建对象的方法分析
- JS面向对象开发 (一)对象的创建
- python面向对象进阶 反射 单例模式
- python-面向对象高级编程
- 用python实现git blob对象的创建和查询
- python数字类型介绍以及创建数字值对象引用、删除数字值引用操作实例
- 「python」创建对象
- python面向对象高级编程
- python入门(二十七):面向对象之封装