【python之路面向对象】初级篇
概述
- 面向过程:根据业务逻辑从上到下写垒代码
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
while True : if cpu利用率 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 |
随着时间的推移,开始使用了函数式编程,增强代码的重用性和可读性,就变成了这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True : if cpu利用率 > 90 % : 发送邮件( 'CPU报警' ) if 硬盘使用空间 > 90 % : 发送邮件( '硬盘报警' ) if 内存占用 > 80 % : 发送邮件( '内存报警' ) |
今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)
注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面向对象编程也支持函数式编程
创建类和对象
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
- class是关键字,表示类
- 创建对象,类名称后加括号即可
ps:类中的函数第一个参数必须是self(详细见:类的三大特性之封装)
类中定义的函数叫做 “方法”
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- #创建类
- class Foo:
- def Bar(self):
- print('Bar')
- def Hello(self,name):
- print('hello %s' %name)
- #根据类Foo创建对象
- foo = Foo()
- foo.Bar() #执行Bar方法
- foo.Hello('SUNXIAO') #执行Hello方法
内部实际传参数的逻辑: foo.Hello('SUNXIAO') --> Hello(self = foo,name = 'SUNXIAO')
诶,你在这里是不是有疑问了?使用函数式编程和面向对象编程方式来执行一个“方法”时函数要比面向对象简便
- 面向对象:【创建对象】【通过对象执行方法】
- 函数编程:【执行函数】
观察上述对比答案则是肯定的,然后并非绝对,场景的不同适合其的编程方式也不同。
总结:
1)函数式的应用场景 --> 各个函数之间是独立且无共用的数据
2)面向对象的使用场景:
A、同一类型的方法具有相同的参数时,直接封装到对象中即可
B、把类当做模板,创建多个对象,对象内封装的数据可以不一样
self详解
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- #创建类
- class Foo:
- def Bar(self):
- print('Bar',self) #self打印:<__main__.Foo object at 0x000001EC4601ADA0>
- def Hello(self,name):
- print('hello %s' %name)
- #根据类Foo创建对象
- foo1 = Foo()
- print(foo1)
- foo1.Bar() #执行Bar方法,打印出:Bar <__main__.Foo object at 0x000001EC4601ADA0>
- #由上面的代码结果可以看出,在执行Bar方法时,python自动将对象foo1传递了Bar方法作为第一个参数
面向对象三大特性
面向对象的三大特性是指:封装、继承和多态。
一、封装
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
所以,在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
第一步:将内容封装到某处
__init__(self)为构造方法,当创建对象时,首先执行的就是构造方法
__del__() 析构方法,当解释器销毁对象时自动调用该方法
self 是一个形式参数,当执行 obj1 = Foo('wupeiqi', 18 ) 时,self 等于 obj1
当执行 obj2 = Foo('alex', 78 ) 时,self 等于 obj2
所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 属性,在内存里类似于下图来保存。
第二步:从某处调用被封装的内容
调用被封装的内容时,有两种情况:
- 通过对象直接调用
- 通过self间接调用
1、通过对象直接调用被封装的内容
上图展示了对象 obj1 和 obj2 在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象.属性名
- class Foo:
- def __init__(self,name,age):
- self.name = name
- self.age = age
- obj1 = Foo('sunxiao',28)
- print(obj1.name) #sunxiao
- print(obj1.age) #
- obj2 = Foo('sunyu','')
- print(obj2.name) #sunyu
- print(obj2.age) #
直接调用
2、通过self间接调用被封装的内容
执行类中的方法时,需要通过self间接调用被封装的内容
- class Foo:
- def __init__(self,name,age):
- self.name = name
- self.age = age
- def detail(self):
- print(self.name)
- print(self.age)
- obj1 = Foo('sunxiao',28)
- obj1.detail() # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18
- obj2 = Foo('sunyu','')
- obj2.detail() # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78
简介调用
综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
练习一:在终端输出如下信息
- 小明,10岁,男,上山去砍柴
- 小明,10岁,男,开车去东北
- 小明,10岁,男,最爱大保健
- 老李,90岁,男,上山去砍柴
- 老李,90岁,男,开车去东北
- 老李,90岁,男,最爱大保健
- 老张...
- def kanchai(name,age,gender):
- print('%s,%s岁,%s,上山去砍柴' %(name,age,gender))
- def qudongbei(name,age,gender):
- print('%s,%s岁,%s,去东北' %(name,age,gender))
- def dabaojian(name,age,gender):
- print('%s,%s岁,%s,大保健' %(name,age,gender))
- kanchai('小敏',20,'男')
- qudongbei('小明',18,'男')
- dabaojian('老张',65,'男')
函数式编程
- class Person:
- def __init__(self,name,age,gender):
- self.name = name
- self.age = age
- self.gender = gender
- def kanchai(self):
- print('%s,%s岁,%s,上山去砍柴' %(self.name,self.age,self.gender))
- def qudongbei(self):
- print('%s,%s岁,%s,开车去东北' %(self.name,self.age,self.gender))
- def dabaojian(self):
- print('%s,%s岁,%s,最爱大保健' %(self.name,self.age,self.gender))
- p1 = Person('xiaoming','','男')
- p1.kanchai()
- p1.qudongbei()
- p2 = Person('老张',65,'男')
- p2.dabaojian()
面向对象编程
上述对比可以看出,如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了... ;而对于面向对象只需要在创建对象时,将所有需要的参数封装到当前对象中,之后再次使用时,通过self间接去当前对象中取值即可。
练习二:游戏人生程序
1、创建三个游戏人物,分别是:
- 梅超风,女,18,初始战斗力1000
- 张三丰,男,20,初始战斗力1800
- 黄蓉,女,19,初始战斗力2500
2、游戏场景,分别:
- 草丛战斗,消耗200战斗力
- 自我修炼,增长100战斗力
- 多人游戏,消耗500战斗力
- #!usr/bin/env python
- #-*- coding:utf-8 -*-
- class Person:
- def __init__(self,name,gender,age,fight):
- self.name = name
- self.gender = gender
- self.age = age
- self.fight = fight
- def grassland(self):
- """注释:草丛战斗,消耗200战斗力"""
- self.fight -= 200
- def practice(self):
- """注释:自我修炼,增长100战斗力"""
- self.fight += 100
- def commandfight(self):
- """多人游戏:消耗500战斗力"""
- self.fight -= 500
- def detail(self):
- temp = '姓名%s;性别%s;年龄%s;战斗力%s' %(self.name,self.gender,self.age,self.fight)
- print(temp)
- p1 = Person('sun','男',100,10000)
- p1.detail()
- p1.commandfight()
- p1.detail()
游戏人生
二、继承
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
例如:
猫可以:喵喵叫、吃、喝、拉、撒
狗可以:汪汪叫、吃、喝、拉、撒
如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,如下所示:
上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:
动物:吃、喝、拉、撒
猫:喵喵叫(猫继承动物的功能)
狗:汪汪叫(狗继承动物的功能)
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Animal:
- def eat(self):
- print('%s吃' %self.name)
- def drink(self):
- print('%s喝' %self.name)
- def shit(self):
- print('%s拉' %self.name)
- def pee(self):
- print('%撒' %self.name)
- class Cat(Animal):
- def __init__(self,name):
- self.name = name
- def cry(self):
- print('喵喵叫')
- class Dog(Animal):
- def __init__(self,name):
- self.name = name
- def cry(self):
- print('汪汪叫')
- dog1 = Dog('老李家的小狗')
- dog1.eat()
- dog1.cry()
- cat1 = Cat('小明家的小猫')
- cat1.drink()
- cat1.cry()
继承实例
所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。
如果子类和父类都存在相同名称的方法,子类对象优先调用子类中的方法,父类对象优先调用父类的方法
那么问题又来了,多继承呢?
- 是否可以继承多个类
- 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python2.7中的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
Python中经典类和新式类的区别:
区别主要体现在继承上:
Python的类可以继承多个类,Java和C#中则只能继承一个类
Python的类如果继承了多个类,那么其寻找方法的方式有两种
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
简单点说就是:经典类是纵向查找,新式类是横向查找
如下例:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Life():
- def daily(self):
- print "繁衍"
- class Animal(Life):
- def daily(self):
- print "吃"
- print "喝"
- print "拉"
- print "撒"
- class Puru(Life):
- def __init__(self):
- pass
- class cat(Puru,Animal):
- def __init__(self):
- print "喵喵"
- a = cat()
- a.daily()
- # 执行结果是:
- # 喵喵
- # 繁衍
python2.7经典类 深度查找
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Life(object):
- def daily(self):
- print "繁衍"
- class Animal(Life):
- def daily(self):
- print "吃"
- print "喝"
- print "拉"
- print "撒"
- class Puru(Life):
- def __init__(self):
- pass
- class cat(Puru,Animal):
- def __init__(self):
- print "喵喵"
- a = cat()
- a.daily()
- # 执行结果是:
- # 喵喵
- # 吃
- # 喝
- # 拉
- # 撒
python2.7新式类 广度查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了很多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
3、python3中不再区分经典类和新式类,只有一种查找方式
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class A:
- def f1(self):
- print("A")
- def Bar(self):
- self.f1()
- class B(A):
- def f1(self):
- print("B")
- class C:
- def f1(self):
- print("C")
- class D(B,C):
- pass
- d = D()
- d.Bar() #B,在执行self.f1()时,因为是D创建的对象,所以也是按照D B A C的顺序查找的
调用顺序易错点
子类执行父类构造方法的两种方式:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Animal:
- def __init__(self):
- print('A构造方法')
- self.ty = "动物"
- def aaa(self):
- print("aaa")
- class Cat(Animal):
- def __init__(self):
- print('B构造方法')
- self.n = '猫'
- #执行父类的构造方法,这样系统会按照上图的规则去父类找init构造方法,所以建议此种方法
- super(Cat,self).__init__()
- #或者用下面方法执行,此种方法随意性比较强,容易混乱
- #Animal.__init__(self)
- b = Cat()
- # B构造方法
- # A构造方法
子类执行父类构造方法
补充:
子类调用父类的构造方法__init__()的两种方法:
- #!/ufr/bin/env python
- # -*- coding:utf-8 -*-
- class Animal:
- def __init__(self):
- print('A构造方法')
- self.ty = '动物'
- class Cat(Animal):
- def __init__(self):
- print('B构造方法')
- self.n = "猫"
- super(Cat, self).__init__() #第一种调用父类的构造方法,推荐这种使用方法,按照python的规则(顺序)去调用
- #Animal.__init__(self) #第二种调用父类的构造方法
- c = Cat()
- print(c.__dict__)
- #结果:
- # B构造方法
- # A构造方法
- #{'n': '猫', 'ty': '动物'}
利用反射导入模块、查找类、创建对象、查找字段
三、多态
Pyhon不支持Java和C#这一类强类型语言中多态的写法,因为python的变量是不区分类型的,所以python原生支持多态,如下例:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class C1:
- def f1(self):
- print('C1')
- class C2:
- def f1(self):
- print('C2')
- def f2(arg):
- arg.f1()
- c1 = C1()
- c2 = C2()
- f2(c1) #C1
- f2(c2) #C2
多态
练习实例:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Weapon:
- def __init__(self,name,limit_level,attack,duration):
- self.name = name #武器名字
- self.limit_level = limit_level #等级限制
- self.attack = attack #攻击
- self.duration = duration #持久 耐久
- class Role: #角色
- def __init__(self,name,blood,base_attack = 100):
- self.name = name #角色名字
- self.blood = blood #血
- self.base_attack = base_attack #基础攻击
- class Magic(Role): #魔法师
- def magic_attack(self,target,weapon):
- """魔法攻击,target为攻击目标,需传入Role的子类对象,weapon,需传入Weapon对象"""
- target.blood -= (weapon.attack + self.base_attack) #目标血量降低=攻击方的基础攻击+攻击方的武器攻击
- magic1 = Magic('笑熬浆糊',3000)
- scarecrow1 = Role('稻草人',500,50)
- mofazhang = Weapon('魔法杖',10,50,100)
- magic1.magic_attack(scarecrow1,mofazhang) #传入被攻击对象和使用武器
- print(scarecrow1.blood)
- magic1.magic_attack(scarecrow1,mofazhang)
- print(scarecrow1.blood)
传奇模仿
扩展:
重载:类中的方法,方法名相同,方法的个数不同,python是不支持重载的,C# JAVA语言中支持重载
重写:子类集成父类可以重写方法,子类对象调用方法的时候优先调用的是子类的方法
四、静态字段、静态方法、类方法、特性(属性)
1、静态字段存在的意义:当类中具有相同字段和值的时候,如果在对象中设置需要每个对象都需要赋值,例如:
静态字段尽量用类去调用,类的方法用对象去调用
- #!/ufr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- country = "China" #创建静态字段,静态字段存储在类中
- def __init__(self,name):
- self.name = name #创建普通字段,普通字段存储在对象中
- def print_name(self):
- print('%s' %(self.name))
- shandong = Province('山东省')
- hebei = Province("河北省")
- shandong.print_name()
- print(hebei.country) #调用静态字段的第1中方法
- print(Province.country) #调用静态字段的第2种方法,推荐使用这种,原则是谁的成员谁调用
- Province.print_name(shandong) #调用类的方法的第1种方法
- shandong.print_name() #调用类的方法的第2种方法,推荐使用这种,原则类的方法由对象调用
静态字段、静态方法、类方法实例:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- country = "China" #创建静态字段,静态字段存储在类中
- def __init__(self,name):
- self.name = name #创建普通字段,普通字段存储在对象中
- def print_name(self):
- print('%s' %(self.name))
- @staticmethod #静态方法,静态方法相当于普通函数
- def static_method(args): #注意静态方法没有self
- print(args)
- @classmethod #类方法
- def class_method(cls): #类方法必须有cls参数,代指类
- cls.static_method(cls.country) #可以直接调用类的静态方法,把静态字段传入
- shandong = Province('山东省')
- hebei = Province("河北省")
- #调用类的普通方法的两种方式
- shandong.print_name()
- Province.print_name(hebei) #可以用这种方式调用方法
- #调用类的静态方法的两种方式
- Province.static_method('类调用静态方法')
- shandong.static_method('shandong对象调用静态方法')
- #调用静态字段的两种方法
- print(Province.country)
- print(shandong.country)
- #类的方法有两种调用方式
- Province.class_method()
- shandong.class_method()
- #总结:虽然有两种方式调用,但潜规则是:
- #1、对象调用:类中的方法、普通字段
- #2、由类调用:静态字段、静态方法、类方法
静态字段、静态方法、类方法
2、特性(属性)
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- def __init__(self,name):
- self.name = name
- @property #特性(属性),只能传递self参数;调用时不用加括号,即以字段的形式调用
- def county(self):
- if self.name == "山东省":
- return ["五莲县","莒县","东港区"]
- else:
- return["未知"]
- shandong = Province("山东省")
- re = shandong.county #特性(属性)的调用方法
- print(re)
特性(属性)实例
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- def __init__(self,name):
- self.name = name
- if self.name == "山东省":
- self.li = ["五莲县","莒县","东港区"]
- else:
- self.li = ["未知"]
- @property #特性(属性),只能传递self参数;调用时不用加括号,即以字段的形式调用
- def county(self):
- return self.li
- @county.setter #当设置特性(属性)时调用此函数
- def county(self,value):
- self.li = value
- shandong = Province("山东省")
- re1 = shandong.county #特性(属性)的调用方法
- print(re1)
- re2 = shandong.county = ["日照市","济南市"] #['日照市', '济南市']
- print(re2)
改变特性(属性)值的方法
成员总结,类的成员有:
对象中: 一般字段、一般方法
类中:静态字段、静态方法、类方法、特性(属性)
其实就是三大类:字段、方法、特性
那么用类还是对象调用呢:只记住一句话,传self的用对象调用,其他的用类调用
3、面向对象之成员修饰符
成员的前面加两个下划线(__)表示私有的,只能在类的内部调用,外部不能调用,只能在成员所属类的内部能访问,其子类和对象都是不能访问的,字段和方法都是适用的
1)静态字段的私有修饰符
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- __country = 'China'
- def __init__(self):
- pass
- def print_country(self):
- return Province.__country
- p = Province()
- #print(Province.__country) #此句报错因为__country是私有静态字段
- print(p.print_country())
静态字段修饰符
成员修饰符:所有成员加两个下划线(__)均可变为私有的,变为私有的后只能在本类中被访问,其继承类中也不能访问。
2)如果想调用私有字段或方法怎么办呢?可以在字符或方法名前面加(_类名.)的方法进行调用,但一般不建议这么做,例如:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Province:
- __country = 'China'
- def __init__(self,name):
- self.__name = name
- def print_country(self):
- return Province.__country
- p = Province("山东")
- print(p._Province__name) #山东
外部调用私有方法或字段
4、类的特殊成员
1)__init__()
2)__del__()
3)__call__(self),类中的call的特殊方法,可以用对象加括号执行。(对象())
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __init__(self):
- print('__init__')
- def __call__(self,*args,**kwargs):
- print('__call__')
- foo = Foo()
- foo() #输出:'__call__'。对象加括号,实际是执行的__call__()函数。两句合起来:Foo()()
4)getitem setitm delitem
foo["key"] 调用 getitem ; foo[1:3] 调用getitem ; python2.x中是调用的getslice
foo["key"] = value 调用setitem ; foot[1:3] = [11,22,33]调用的是setitem;python2.x中调用的是setslice
del foo["key"] 调用delitem; del foor[1:3] 调用的是delitem ; python2.x中调用的是delslice
例如:
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __init__(self):
- pass
- def __getitem__(self,item): #对应的是:foo["key"]
- print(item)
- def __setitem__(self, key, value): #对应的是:foo["key"] = "value"
- print("%s:%s" %(key,value))
- def __delitem__(self, key): #对应的是:del foo["key"]
- print('delte this' + key)
- foo = Foo()
- foo['key']
- foo["key"] = "value"
- del foo["key"]
字典方式的执行方法
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __init__(self):
- pass
- def __getitem__(self,item): #对应的是:foo[1:20:2]
- print(item.indices(100)) #最大值为100,将slice对象转为元组(1, 20, 2)
- def __setitem__(self, key, value): #对应的是:foo[1:3] = [11,22]
- emp = key.indices(100)
- print(emp,value)
- def __delitem__(self, key): #对应的是:del foo[1:3]
- print(key.indices(100))
- foo = Foo()
- foo[1:20:2] #打印:(1, 20, 2)
- foo[1:3] = [11,22] #打印输出:(1, 3, 1) [11, 22]
- del foo[1:3] #打印输出:(1, 3, 1)
- #slice.indices()
切片特殊方法用法
5)类的特殊成员之__dict__ ,查看对象或类中的成员
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __init__(self):
- self.name = 'sunshuhai'
- def hello(self):
- pass
- foo = Foo()
- print(foo.__dict__) #查看对象中的成员
- print(Foo.__dict__) #查看类中的成员
__dict__
6)特殊成员之__iter__(self)方法
当for循环类的对象时,实际执行的就是类中的__iter__(self)方法
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __iter__(self):
- yield 1
- yield 2
- yield 3
- foo = Foo()
- for i in foo: #当循环对象时,实际执行的是特殊方法__iter__(self)
- print(i)
特殊方法__iter__(self)
7)类的特殊成员之__str__(self)
在用print打印对象,或将对象转为字符串时,会自动执行__str__(self)方法
- #!usr/bin/env python
- # -*- coding:utf-8 -*-
- class Foo:
- def __init__(self,ef):
- self.ef = ef
- def __str__(self):
- return self.ef
- exception = Foo('出错了。。。。')
- print(exception) #出错了。。。。,实际调用的是__str__(self)方法
类的特殊方法__str__(self)
8)了解:类的特殊成员之new和metaclass
类是由对象Type创建的
【python之路面向对象】初级篇的更多相关文章
- python之路 面向对象进阶篇
一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 countr ...
- 第四篇:python 高级之面向对象初级
python 高级之面向对象初级 python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 ...
- Python 正则表达式入门(初级篇)
Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写. 转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达 ...
- python 高级之面向对象初级
python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...
- Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...
- 转载 Python 正则表达式入门(初级篇)
Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写.转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式 ...
- 【Python之路】特别篇--Python面向对象(初级篇)
概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最易被初学 ...
- python 面向对象初级篇
Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...
- 【Python之路】特别篇--Python面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- Python之路【第九篇】:Python面向对象
阅读目录 一.三大编程范式 编程范式即编程的方法论,标识一种编程风格: 大家学习了基本的python语法后,大家可以写python代码了,然后每个人写代码的风格不同,这些不同的风格就代表了不同的流派: ...
随机推荐
- lxml etree对存在的xml添加新节点,新节点没有排版格式化
新添加的时候如果不做处理,是这个样子 要在解析xml加上 parser = etree.XMLParser(remove_blank_text=True)xml = etree.parse(major ...
- android中实现监听的四种方法
(1)自身类作为事件监听器 package cn.edu.gdmec.s07150745.work5; import android.support.v7.app.AppCompatActivity; ...
- 模块介绍/time/os...
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...
- 中国剩余定理模数互质的情况模板(poj1006
http://poj.org/problem?id=1006 #include <iostream> #include <cstdio> #include <queue& ...
- selenium借助AutoIt识别上传(下载)详解【转】
AutoIt目前最新是v3版本,这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)中进行自动化操作.它利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动 ...
- 2016.9.15初中部上午NOIP普及组比赛总结
2016.9.15初中部上午NOIP普及组比赛总结 2016.09.15[初中部 NOIP普及组 ]模拟赛 又翻车了!表示时超和空超很可恨! 进度 比赛:AC+0+0+20=120 改题:AC+80+ ...
- 廖雪峰Java11多线程编程-2线程同步-4wait和notify
wait和notify synchronized解决了多线程竞争的问题 我们可以在synchronized块中安全的对一个变量进行修改,但是它没有解决多线程协调的问题. 例如设计一个TaskQueue ...
- 使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置
1.使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置 2.上代码:在resources目录下新建:generatorConfiguration.xml文 ...
- Zuul微服务网关
Zuul简介: Zuul是Netflix开源的微服务网关,它可以和Eureka.Ribbon.Hystrix等组件配合使用.Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能 ...
- jeecms v9修改后台访问地址
将jeeadmin/jeecms/index.do 改为admin/index.do为例 修改WebContent\WEB-INF\web.xml <servlet-mapping> &l ...