九 Python面向对象

九 Python面向对象

1. 面向对象与面向过程

1-1. 介绍

面向对象编程:Object Oriented Programming,简称OOP,是一种程序设计方法。

1-2. 概念及术语

术语 概念及介绍
类(Class) 用来描述具有相同属性和方法的对象的集合。它定义了该集合中每个对 象所共有的属性和方法。其中的对象被称作类的实例。
实例 也称对象。通过类定义的初始化方法,赋予具体的值,成为一个"有血有肉 的实体"。
实例化 创建类的实例的过程或操作。
实例变量 定义在实例中的变量,只作用于当前实例。
类变量 类变量是所有实例公有的变量。类变量定义在类中,但在方法体之外。
数据成员 类变量、实例变量、方法、类方法、静态方法和属性等的统称。
方法 类中定义的函数
静态方法 不需要实例化就可以由类执行的方法
类方法 类方法是将类本身作为对象进行操作的方法。
方法重写 如果从父类继承的方法不能满足子类的需求,可以对父类的方法 进行改写,这个过程也称override。
封装 将内部实现包裹起来,对外透明,提供api接口进行调用的机制。
继承 即一个派生类(derived class)继承父类(base class)的变量和方法。
多态 根据对象类型的不同以不同的方式进行处理。

1-3. 区别

面向过程:根据业务逻辑从上到下写代码
面向对象:将数据与函数绑定到一起,进行封装。减少重复代码的重写过程

1-4. 示例参考

示例1:面向过程

def stu_info(name,age,gender):
    print(name,age,gender)

stu_info("oldli","18","male")
stu_info("ellen","18","male")
stu_info("bruin","18","male")

示例2:面向对象

class Students(object):
    def stu_info(self,name, age, gender):
        print(name, age, gender)

s = Students()
s.stu_info("oldli","18","male")
s.stu_info("ellen","18","male")
s.stu_info("bruin","18","male")

2. 面向对象之(类)

2-1. 介绍

类是抽象的模板,用来描述具有相同属性和方法的对象的集合,比如 Animal类。
类名通常采用驼峰式命名,尽量让字面意思体现出类的作用。

2-2. 结构

Python使用class关键字来定义类,结构如下:

class 类名(object): # object 可有可无
	def 方法名(self,参数): # 行为
		pass
name = 类名() # 定义一个实例对象
name.方法名(参数) # 调用

3. 面向对象之 (self)

3-1. 介绍

self 形参
self 是对象本身,也就是说,当创建的对象是谁时,self就是谁

3-2. 示例参考

class Student(object):
    def test(self):
        # print(self)
        pass

oldli = Student() # 实例化对象
print(oldli)
oldli.test()

Chy = Student() # 实例化对象
print(Chy)
Chy.test() # 调用类
# 输出结果
#<__main__.Student object at 0x03955190>
#<__main__.Student object at 0x039552C8>
class Student(object):
    def info(self):
        print(self.name,self.age)

marshal = Student()
marshal.name = "marshal"
marshal.age = "18"
# print(marshal)
marshal.info() # 输出结果 marshl 18

xiaoming = Student() # 实例化对象
xiaoming.name = "xiaoming"
xiaoming.age = "22"
# print(marshal)
xiaoming.info() # 输出结果 xiaoming 22
  1. 当只有一个变量,其它相同时,可以参考这个
class Students(object):
    def stu_info(self,name):
        print(name, self.age, self.gender)

s = Students() # 实例化对象
s.age = "18"
s.gender = "male"
s.stu_info("oldli")
s.stu_info("ellen")
s.stu_info("bruin")
'''
输出结果:
oldli 18 male
ellen 18 male
bruin 18 male
'''

4. 面向对象之 init 魔法方法

4-1. 介绍

# 构造方法(初始化方法)
def __init__(self):
	pass
# 特殊意义
	创建对象的同时,通过对象执行这样的一个方法,叫做构造方法

4-2. 示例参考

class students(object):
	def __init__(self,age,gender):
	#属性
	self.age = age
	self.gender = gender
	self.addr = "ChongQing"
	
	# 打印信息
	def stu_info(self,name):
		print(name,self.age,self.gender,self.addr)
s = students() # 实例化对象
s.stu_info("oldli")
s.stu_info("enlen")
s.stu_info("bruin")
# 输出结果:
# oldli 18 male ChangSha
# ellen 18 male ChangSha
# bruin 18 male ChangSha

5. 面向对象之 str 魔法方法

5-1. 介绍

tips: 使用了该函数,一定返回字符串;如果返回出错,可以
定义的 str

def __str__(self):
	pass 
# 1. return 关键字 将我们的信息直接返回对象
# 2. 只能时str 如果非字符串 str() 强转

5-2. 示例参考

class People(object):
	def __init__(self):
		self.age = 18
		self.name = "zero"
		self.hobby = "play game"
	
	def __str__(self):
		return str({
     "name":self.name,"age":self.age})
		# return 返回的多个值 元组
        # 一定返回字符串

zero = People() 
print(zero) # 输出结果: {'name':'zero',

6. 练习

‘’‘只有当年龄>0的时候才返回出来,否则默认为0岁’’’

class People(object):
	def __init__(self): # 初始化参数
		self.age = 0

	def set_age(self,new_age): # 判断
		if new_age >= 0 and new_age <=120:
			self.age = new_age
		elif new_age > 120:
			self.age = 0
		else:
			# abs()取绝对值的内置方法
			self.age = abs(new_age)
	def get_age(self):
		return self.age

xiaoming = People() # 实例化对象
xiaoming.set_age(10) # 调用函数
print(xiaoming.get_age())
# 输出结果为 10

7. 私有属性与方法

7-1. 介绍

在类中,不希望外部去访问我的属性。
格式:

# 私有属性 -->__属性名():

7-2. 私有属性示例参考

# 定义一个类
class People(object):
	def __init__(self): # 初始化参数
		self.__age = 18 # 私有属性,外部访问不了
		self.name = zero

	def get_age(self): # 可从内部调用私有属性
		print(self.__age)

	def set_age(self,age):
		self.__age = age

zero = People() # 实例化对象
print(zero.name) # 打印取出名字  输出结果 zero
print(zero.__age) # 会报错,no attribute 。 不能直接从外部调用私有的属性(__age)
zero.get_age() # 调用get_age 方法获取私有属性 输出结果18
zero.set_age(22) # 重新传入参数
zero.get_age() # 输出结果 22 
print(zero.__dir__()) # 查看对象的方法跟属性

7-3. 私有方法示例参考

定义私有方法

class Demo(object): # 定义一个类
	def test1(self):
		print("test1:)
	
	def __test2(self):
		print("test2")

d = Demo() # 实例化对象
d.test1()	# 输出结果为 test1
d.__test2() # 报错,不能调用

8. 成员-方法与属性

8-1. 示例1 静态属性

class Province(object):
	country = "中国"  # 类属性, 静态属性  对象, 类来调用

	def __init__(self,name):
		self.name = name

	def print_info(self):
		print(Province.country,self.name) # 静态属性调用 类名.静态属性名

guangdong = Province("广东")
chongqing = Province("重庆")
guangdong.print_info() # 输出结果 中国广东
chongqing.print_info() # 输出结果 中国重庆
  1. 实例方法:对象需要保存的一些值,执行某功能时,需要使用对象中的值
    静态方法:跟我们在函数外部定义独立的方法没有什么区别,但是有的时方便维护。不需要创建对象 直接访问,不需要self参数。调用 通过类调用
    类方法: 保存在类中 由类直接调用 cls–>当前类
class Demo(object):
	def __init__(self):
		self.name = "zero"

	def test(self):
		print(self.name)

	@staticmethod # 静态方法,等同于上面的
	def test1(name):
		print(name)

	@classmethod
	def class_md(cls):
		print(cls)

d = Demo() # 实例化对象
d.test()  # 输出结果 zero
Demo.test1("王先生") # 输出结果 王先生 调用了静态属性@staticmethod
d.test1("小周") # 输出结果 小周

Demo.class_md() # 

8-2. 在类中如何实现当前格式化时间

  1. 面向过程
import time
def show_time():
	print(time.strftime("%H:%M:%S",time.localtime()))

show_time() # 输出结果, 当前时间
  1. 面向对象
import time
class TimeTest(object):

	@staticmethod
	def show_time():
		print(time.strftime("%H:%M:%S",time.localtime()))

nowtime = Timetest()
TimeTest.showtime() # 输出结果, 当前时间

8-3. property

8-3-1. 介绍

可以将类的方法变为属性

8-3-2. 示例参考

class Demo(object):
	def __init__(self):
		self.name = "zero"

	@property  # 将方法变为属性
	def test(self):
		print(self.name)
		return "test"

	@test.setter   # d.test = "456"
	def test(self,nums):
		print(nums)

	@test.deleter
	def test(self):
		print(1111)

d = Demo() # 实例化对象
print(d.name)
res = d.test
print(res)

d.test = "456"  # 想要改变

del d.test
  1. 制作翻页效果
class Page(object):
	def __init__(self,current_page):
		try:
			p = int(current_page)
		except Exception as e: # 万能异常捕获
			p = 1
		self.page = p

	@property
	def start(self):
		start = (self.page-1)*10
		return start

	@property
	def end(self):
		end = self.page * 10
		return end

li = list(range(100))

while True:
	p = int(input("请输入要查看的页码:"))
	page = page(p)  # 实例化对象
	print(li[page.start:page.end])

9. 函数的继承

9-1. 介绍

创建新类的方式,新类可以继承一个或者多个父类;
作用:避免重复造轮子
新式类 继承object
经典类 不继承object

tips:
如果调用的是继承的父类中的方法,可以在这个公有方法中访问父类中的私有属性和私有方法;
但是如果在子类中实现了一个公有方法,那么这个方法是不能够调用继承的父类中的私有方法和私有属性

class Father(object):
    def __init__(self):
        self.name = "amy"
        self.__age = 18

    def __test(self):
        print("__test")

    def test1(self):
        print(self.__age)


class Son(Father):
    # def __init__(self):
    #     print("Son")
    #     super().__init__()
    def test3(self):
        # print(self.__age)
        self.__test()

    def __test(self):
        print("__test")


s = Son()
print(s.name)  #	amy
# print(s.__age)  # 私有属性不会被继承
# s.__test()  #私有方法不会被继承
# s.test1()
s.test3() #	__test

9-2. 示例

class GrandFather(object):
	def sleep(self):
		print("睡10个小时")

class Father(GrandFather): # 父类 基类
	def run(self):
		print("我会跑")

	def eat(self):
		print("我会吃")

class Son(Father):
	def study_python(self):
		print("我学python")

s = Son()
# 子类没有, 就往父类中去找
s.run() # 输出结果 我会跑
s.study_python() # 输出结果 我学python
# 父类没有 就会往父类的父类中去找
s.sleep()	#	输出结果 睡10个小时

9-3. 多继承

示例:

class GrandFather(object):
	def sleep(self):
		print("GrangF睡觉")

class Father(GrandFather):
	def run(self):
		print("Father会跑")

class Father1(Father):
	def run(self):
		print("Father1会跑")

	def sleep(self):
		print("Father1睡觉")

class Son(Father,Father1):
	pass

s = Son()
s.run()
s.sleep()	# C3
# print(Son.__mro__) # 可以查看调用顺序

tips:

  1. 左边优先
  2. 当左边父类的父类,有该方法。右边父类有该方法。左边一条路走到底
  3. 他们有一个根,根最后执行

10. 函数重写

10-1. 示例

'''
重写的同时并且执行父类中的方法
'''
class GrandFather(object):
	def sleep(self):
		print("睡10个小时")

class Father(GrandFather):
	def run(self):
		print("我会跑")

	def eat(self):
		print("我会吃")

class Son(Father):
	def study_python(self):
		print("我学python")

	def sleep(self):
		print("我睡8个小时")
		#super(Son,self).sleep()	#	下面的完整版
		super().sleep()	#	效果同上
		#GrandFather.sleep(self)	#	效果同上

s = Son()
s.sleep() # 输出结果 我睡8个小时 睡10个小时

总结:

  1. 继承机制 深度优先 先从自己找 自己找不到 就往父类找
  2. 重写 防止执行父类的该方法
  3. self 都指当前实例化的对象
  4. 既想要继承父类当中方法 又想拓展新的东西
    4.1 super(cls,self).父类中的方法(para)
    4.2 父类名父类中的方法(self,para)

11. 多态

示例:

class Person(object):
	def print_info(self):
		print("我是个人")

class Girl(Person): # 继承
	def print_info(self):
		print("我是zero")

def info(travel): # 定义一个函数
	travel.print_info()

zero = Person() # 实例化对象
info(zero)  # 我是个人

zero1 = Girl() # 实例化对象
info(zero1)	# 我是zero

12. 面向对象之魔法方法

12-1. 魔法方法

  1. doc
    tips:
    当函数中有多个注释时,只会打印第一个注释
# str()
# print(str().__doc__)

class Demo(object):
	'''
我是Demo的注释
	'''
	'我有一个构造方法'
    "我....."
	def __init__(self):
		pass

d = Demo()
print(d.__doc__) #	输出结果:我是demo的注释
  1. del
    tips:
    只有等到对象全部释放,才会主动触发__del__
class Demo:
	def __del__(self):
		print("好惨,我被回收了")

d = Demo()
d1 = d
print("-"*20)
del d
del d1
print("-"*20)

'''
输出结果:
--------------------
好惨,我被回收了
--------------------
'''
  1. call
    tips:
    一个实例,也可以变成一个可调用的对象
class Demo(object):
	def __call__(self,*args,**kwargs):
		print("我可以调用了哟")

d = Demo()
d() # 'Demo' object is not callable # 输出结果: 我可以被调用了哟
# str()
  1. dict 查看类或者对象的成员 字典
    dict 更像__dir__的一个子集
class Demo(object):
	gender = "female"
	def __init__(self):
		self.name = "zero"
		self.__age = 18

	def test(self):
		print("test")

d = Demo()
d.test()
print(d.__dict__) # dict 查看对象中的实例属性
print(Demo.__dict__) #	查看类中的成员 -->类属性与行为
print(d.__dir__()) #	列表 查看对象的 -->成员
print(Demo.__dir__(d))
print(d._Demo__age)

12-2. new方法

12-2-1. 介绍

new 在类准备自身实例化时调用的
new 静态方法 创建对象
init 实例方法,对象自动调用的方法

12-2-2. 示例

class Demo(object):
	def __init__(self):
		print("__init__")

	# 如果我们这个类中没有new,会创建对象的时候,会自动执行父类中的new方法
	def __new__(cls,*args,**kwargs):
		return super().__new__(cls) # 传入别的类名时,不会调用__init__方法

d = Demo()
# 1.创建对象 __new__
# 2.调用__init__方法
# 3.返回对象引用

12-3. 单例模式

12-3-1. 介绍

永远只使用一份对象 (重点:记录日志在logger)
对象不存在时候 -->创建对象
对象存在 -->永远只返回当前创建对象

12-3-2. 示例

class Demo(object):
	flag = None	#	标志

	# 创建对象 __new__
	def __new__(cls,*args,**kwargs):
		# return super().__new__(cls)
		if cls.fflag is None:
			cls.flag = super().__new__(cls):
			return cls.flag
		else:
			return cls.flag

d = Demo()
print(id(d))
d1 = Demo()
print(id(d1)) # 输出两个相同的ID地址

12-4. reflect 反射

12-4-1. 会用到的函数

  1. getattr 函数 获取属性值或者获取方法变量的地址
getattr(py文件名,输入的名字)

getattr(views,ipt)
  1. hasattr 函数 判断是否有此变量,返回bool 值

你可能感兴趣的:(Python,Python,面向对象)