Python学习---面向对象的学习[基础]
面向对象
面向对象的三大特性是指:封装、继承和多态。
说明: Python可以函数式编程,也可以面向对象编程
l 面向过程:根据业务逻辑从上到下写垒代码
l 函数式 :将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
l 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
面向对象使用场景: 多个函数中,有相同的参数时,考虑面向对象编程【sql连接等】
需要封装一部分内容的时候,就考虑用类解决
函数和面向对象的区别:定义 + 执行的区别
类的创建以及self的含义:self代表调用该方法的执行对象
class Bar:
def foo(self, name, age, gender, content):
print(self.school, self.haha, name, age, gender, content)
z = Bar()
z.school = 'peking'
z.haha = 'hhh'
print(z.school)
z.foo('ftl', 123, 'male', 'hello world')
构造方法
构造方法__init__(self, args): 函数的初始化的时候自动执行
class Bar:
# 构造方法
def __init__(self, name, age, gender, content):
self.name = name
self.age = age
self.gender = gender
self.content = content
self.boold = 'O' # 初始化默认的参数
print('__init__') # __init__
print(name, age, gender, content, self.boold) # hhh 23 male hello world
z = Bar('hhh', 23, 'male', 'hello world') # hhh 23 male hello world O
父类调用
1. super的调用:super(子类函数名, 调用的self), eg, super(Son, self),先认儿子,再找调用者
2. Father.__init__(self): 由父类名直接调用,我们由对象调用方法的时候,Py会自动帮我们传递self参数,但是由Father类直接调用的时候,需要把调用对象z传递过去。
class Father:
def __init__(self):
print('Father')
def hello(self):
print('Father:hello')
class Son(Father):
def __init__(self):
# super(Son, self).__init__()# 这里super(子类名,self)调用父类的init方法
Father.__init__(self) # 这里父类名.方法(self) 调用父类方法
# 父类名调用的时候,缺少参数报错 __init__() missing 1 required positional argument: 'self'
print('Son')
def hello(self):
print('Son:hello')
super(Son, self).hello() # 调用父类的方法
def world(self):
print('son:world')
z = Son()
z.hello()
z.world()
封装性
将内容封装到某个地方,以后再去调用被封装在某处的内容。
特 性:
将内容封装到某处
从某处调用被封装的内容
class Bar:
def foo(self, content):
print(self.name, self.age, self.gender, content)
z = Bar()
z.name = 'ftl'
z.age = 12
z.gender = 'male'
z.foo('hello world') # ftl 12 male hello world
继承性:
子可以继承父的内容。将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
继承:先在子类自己的方法中查找,然后再去父类的方法查找
class Father:
def __init__(self):
print('Father')
def hello(self):
print('Father:hello')
class Son(Father):
# def __init__(self):
# print('Son') # 子类的构造方法没有覆盖父类,则xian执行父类的构造方法
def __init__(self): # 这里的子类覆盖掉了父类的init方法,所以打印子类自己的print
print('Son')
def world(self):
print('son:world')
z = Son() # Son
z.hello() #Father:hello
z.world() # son:world
多继承:
a. 左侧优先
b. 一条道走到黑
c. 同一个根时,根最后执行
d. self代表调用的函数对象,遇到self调用函数的时候,确定self是谁的对象,然后一定是回到原点开始往上找方法的
class BaseRequest():
pass
class RequestHandler(BaseRequest):
def server_forver(self):
print('RequestHandler: server_forver')
self.process_request() # 回到起点开始网上找,结果:Minx : process_request def process_request(self):
print('RequestHandler: process_request')
class Minx:
def process_request(self):
print('Minx : process_request') class Son(Minx, RequestHandler):
pass s = Son()
s.process_request() # Minx : process_request
s.server_forver() # RequestHandler: server_forver
多态性
Python自带多态的特性,因为Python会自动判断你传入的参数是什么类型,不用特别声明
def foo(args):
print(args)
foo("hello world") # hello world
foo(1234567) # 1234567
类的一个小程序:
类的成员
类的成员:
字段: 2种
方法: 3种
属性: 1种
特殊成员:
1种
普通字段属于对象,只能通过对象访问
静态字段属于类,可以通过对象,也可以通过类
class province:
country = 'China' #创建全局变量country, 她是类的对象,创建类的时候生成
# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性
def __init__(self, name):
self.name = name
print(self.name, province.country) henan = province('henan')
print(province.country) # 可以通过类调用,也可以通过类调用
print(henan.country) # 可以通过对象调用,也可以通过类调用
# print(province.name) # 不能通过对象查找类 type object 'province' has no attribute 'name'
方法:方法保存在类中,可以通过类查找,也可以通过对象调用,但是前提是都要先创建一个类的对象
class Province:
country = 'China' # 创建全局变量country, 她是类的对象,创建类的时候生成
# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性
def __init__(self, name):
self.name = name
def fun(self):
print(self.name, Province.country)
henan = Province('henan')
henan.fun() #推荐使用
# Province.fun() #需要传递对象过去 fun() missing 1 required positional argument: 'self'
Province.fun(henan)
静态方法:@ staticmethod装饰器来完成静态方法,此时可以省略self参数,直接由类调用
class Province:
country = 'China' # 创建全局变量country, 她是类的对象,创建类的时候生成
# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性
def __init__(self, name):
self.name = name
@staticmethod
def fun(city, house): # 可以不用传递self参数
print(Province.country, city, house)
henan = Province('henan')
henan.fun('HuNan', 'Chaoyang')
Province.fun('HuNan', 'Chaoyang') # 推荐使用,直接用类调用,此时的self参数可以不用传递
类方法:由类直接调用,必须传递一个形式参数,此时python会自动帮我们传递一个类名过去,所以一般命名为cls
class Province:
@classmethod
def class_method(cls): #必须传递一个形式参数,python自动传递类名过去
# cls 是类名,不依赖对象
print('class_method:', cls) # 此时python会自动帮我们传递一个类名过去
Province.class_method() # 由类直接调用,此时python会自动帮我们传递一个类名过去 # 结果: class_method: <class '__main__.Province'>
属性(@property):定义的时候像方法,而且也有返回值, 使用的时候像字段
class Province:
@property
def fun(self):
print('hello world')
return 'ok'
obj = Province()
ok = obj.fun
print(ok) # hello world
属性表达一:(@fun.setter/@fun.deleter):仅仅是对应关系
class Province:
@property # 用于执行obj.fun 接收值
def fun(self):
print('hello world')
return 'ok'
@fun.setter # 用于obj.fun = 123 ,重新赋值
def fun(self, val):
print(val) @fun.deleter # 仅仅是一个对应关系,不涉及真正的删除
def fun(self):
print('delete')
obj = Province()
ok = obj.fun
print(ok)
obj.fun = 'hello Python' # 查找对应的关系
del obj.fun # 不会真正的执行删除的操作,仅仅只是一个对应关系
属性表达二:(property函数):仅仅是对应关系
class Page:
def f1(self):
return 'hhh'
def f2(self, val):
print(val)
def f3(self):
print('del')
pp = property(fget=f1, fset=f2, fdel=f3, doc='Property用法二') p = Page()
# ret = p.f1()
# print(ret) print(p.pp) # hhh
p.pp='hello' # hello
del p.pp # del
利用属性实现分页
class Page:
def __init__(self, page):
try:
page = int(page)
except Exception as e:
page = 1
self.page = page
@property
def start(self):
page = (self.page - 1) * 10
return page
@property
def end(self):
page = self.page * 10
return page
li = []
for i in range(100):
li.append(i)
while True:
page = input("请输入页码:")
obj = Page(page)
print(li[obj.start:obj.end])
成员修饰符
公有成员 默认公有
私有成员 __小写字段名 不能直接访问,只能间接访问
继承也不能访问父类的私有字段,只能访问共有字段
class Foo:
__school = 'xupt' # 静态私有字段,外部无法直接访问
def __init__(self, name, age):
self.name = name
# self.age = age
self.__age = age # 私有变量,外部无法直接访问
def show(self):
print(self.__age, self.__school) # 从内部简介访问
@staticmethod
def stat():
print(Foo.__school)
def __private(self):
print('privatemethod')
def f(self):
self.__private()
obj = Foo('hhh', 12)
obj.show() # 12 xupt
Foo.stat() # xupt
obj.f() # privatemethod
子类不能访问父类的私有变量
class F:
def __init__(self):
self.f_name = 'Father'
# self.__fage = 54 # 父类的私有变量 class S(F):
def __init__(self, name, age):
F.__init__(self)
self.name = name
self.__age = age def show(self):
print(self.__age, self.name) def showFather(self):
print(self.f_name)
print(self.__fage) # 报错,父类的私有变量
obj = S('hhh', 23)
obj.show() # 23 hhh
obj.showFather() # Father
特殊成员
__init__ 类()自动执行
__del__ 析构方法,对象被销毁时自动触发,Py自动执行
__call__ 对象() 类()() 自动执行
__int__ int(对象)
__str__ str()
__add__
__dict__ # 讲对象中封装的所有内容通过字典的形式返回
__getitem__ # 切片(slice类型)或者索引
__setitem__
__delitem__
__iter__
# 如果类中有 __iter__ 方法,对象=》可迭代对象
# 对象.__iter__() 的返回值: 迭代器
# for 循环,迭代器,next
# for 循环,可迭代对象,对象.__iter__(),迭代器,next
# 1、执行li对象的类F类中的 __iter__方法,并获取其返回值
# 2、循环上一步中返回的对象
__call__ 对象() 类()() 自动执行
class F:
def __init__(self, name, age):
self.name = name
self.age = age
print(self.name, self.age)
def __call__(self, *args, **kwargs):
print('Call') obj = F('hhh', 23)
obj() # 等价于 F('hhh', 23)() 对象也可以添加()来执行
__int__/__str__/__add__
class F:
def __init__(self, name):
self.name = name
def __int__(self):
return 1234
def __str__(self):
return 'Father'
def __add__(self, other): # 对象的重组
# self= f('hello')
# other = ff('world')
return self.name + other.name
f = F('hello')
ff = F('world')
# print(f+ff) # 没有add方法,报错, unsupported operand type(s) for +: 'F' and 'F'
print(f+ff) # helloworld, 2个对象相加时候,会执行第一个对象的__add方法,并且将第二个对象作为参数传递过去
print(int(f)) # 1234, 对象转换为int型
print(str(f)) # Father, 对象转换为str型
__dict__ # 将对象/类中封装的所有内容通过字典的形式返回
class F:
# hello我让ld
def __init__(self, name):
self.name = name
def show(self):
print(self.__dict__)
f = F('hello')
f.show() # 打印对象里面的所有成员
print(F.__dict__) # 打印类里面的所有成员
__getitem__/__setitem__/__delitem__的使用
# 问: li本身也是一个对象,为什么可以直接用下标来取值呢?
# 答; 因为list里面有__getitem__, __setitem__, __delitem__
li = ['hello', 'world', '2017']
print(li[1])
# print(li[1:4:2])
li[1] = 'ftl'
del li[1]
# 函数利用使用__ getitem__
lass F:
def __init__(self, name):
self.name = name
def __getitem__(self, item):
if type(item) == 'slice':
print('这里采用切片调用',item.start, item.stop, item.step)
else:
print('这里采用索引调用')
return item
def __setitem__(self, key, value):
print(key, value)
def __delitem__(self, key):
print(key)
obj = F('hello')
print(obj['hello'])
obj['hello']='world'
del obj['hello']
__iter__: 迭代器的原理
class F: def __init__(self, name, age):
self.name = name
self.age = age def __iter__(self): # 代表F是一个可迭代对象
return iter([1, 2, 3, 4, 5]) # 返回一个迭代器 f = F('hhh', 23)
for i in f: # for循环循环next()迭代打印
print(i)
【学习参考】http://www.cnblogs.com/wupeiqi/p/4493506.html
Python学习---面向对象的学习[基础]的更多相关文章
- Python之面向对象编程学习
不知不觉,学到了python的面向对象编程思想.今天我们来讨论下面向对象编程的思想. 顾名思义,面向对象,就是面向于对象,这里所说的对象不是你现实生活中你的女朋友,你的老婆,你的爱人,在编程的世界里面 ...
- 【我要学python】面向对象系统学习
第一节:初识类的定义和调用 c1.py #类 = 面向对象 #类 最基本作用:封装 #类中不仅可以定义变量 还可以定义函数等等,例: class student( ): name = ' ' age ...
- Python学习---面向对象的学习[深入]
类的深入学习 a. Python中一切事物都是对象 b. class Foo: pass obj = Foo() # ...
- PyTorch框架+Python 3面向对象编程学习笔记
一.CNN情感分类中的面向对象部分 sparse.py super(Embedding, self).__init__() 表示需要父类初始化,即要运行父类的_init_(),如果没有这个,则要自定义 ...
- 零基础学Python不迷茫——基本学习路线及教程!
什么是Python? 在过去的2018年里,Python成功的证明了它自己有多火,它那“简洁”与明了的语言成功的吸引了大批程序员与大数据应用这的注意,的确,它的实用性的确是配的上它的热度. Pyt ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python学习之路-Day1-Python基础
学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...
- Python学习一:序列基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
随机推荐
- switch表达式、case穿透
记得第一次学switch的时候那是还是学习c语言的时候,整体的写if-else,switch,现在回想起来已经是很多年前的事了,好了今天让我们再来回顾下简单的switch 语法 switch(n) { ...
- 看过ruby相关书籍
<ruby编程语言> <crafting rails applications> <agile web developemnt> <build awesome ...
- springboot-3-aop
aop存在的目的是进一步解耦, spring支持aspectJ的注解式切面编程 1), 使用@Aspect声明为一个切面, 并使用@Component加入context中 2), 使用@After, ...
- WPF中用后台C#代码为TabItem设置Background属性
TabItem tabItem = sender as TabItem; tabItem.Background = new ImageBrush(new BitmapImage(new Uri(@&q ...
- PHP学习1——快速入门
主要内容: 搭建PHP开发环境 第一个helloworld程序 PHP(Hypertext Preprocessor)PHP超文本预处理程序,是一种嵌入HTML的脚本语言,运行在服务器. 搭建PHP开 ...
- C#中的分部类和分部方法:partial
这篇文章主要介绍了C#中的分部类和分部方法,讲解了类的拆分和方法的定义的拆分,需要的朋友可以参考下可以将类或结构.接口或方法的定义拆分到两个或多个源文件中.每个源文件包含类型或方法定义的一部分,编译应 ...
- Cheatsheet: 2018 01.01 ~ 02.28
JAVA How to Improve the Performance of a Java Application Java Memory Management Writing Java Micros ...
- [C语言] 数据结构-预备知识结构体
结构体 为什么出现结构体 为了表示一些复杂的数据,而普通的基本类型变量无法满足需求 什么叫结构体 结构体是用户根据实际需要自己定义的复合数据类型 如何使用结构体 1.两种方式 一般使用结构体指针的形 ...
- 使用webClient实现图片同步,异步下载
WebClient.DownloadFile 方法 将具有指定 URI 的资源下载到本地文件. 命名空间:System.Net 程序集:System(在 system.dll 中) 同步实现参考代码: ...
- C#学习笔记(基础知识回顾)之值传递和引用传递
一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...