Notes on Python Basics --类与对象--Day8

Day -8

Author: Denny YU
Created: January 15, 2022 9:09 PM

类与对象进阶

属性和方法

1. 类的私有属性和私有方法实现封装

  1. 通畅约定两个下划线开头的属性是private,其他为公共的public
  2. 类内部可以访问私有属性(方法)
  3. 类外部不能直接访问私有属性(方法)ps:但是可以以某种方式访问
  4. 类外部可以通过“_类名__私有属性名”访问私有属性
class Employee:
	def __init__(self,name,age):
		self.name=name
		self.__age=age ##私有属性
	def work(self):
		print("I like work")
	def __work(self):
		print("after {1} was {0} heavy work".format(self.name,self.__age)) ##私有方法

e=Employee("jing", 18)

print(e.name) 
#print(e.age) #会输出错误AttributeError: 'Employee' object has no attribute 'age'
print(e._Employee__age) #输出18
e._Employee__work() #输出“heavy work”
e.work()

2. 方法没有重载

在其他语言,可以定义多个重名的方法,只要保证方法签名唯一即可。 方法签名包含三个部分:方法名、参数数量、参数类型

Python总共方法的参数没有类型,参数的数量也是可变的。因此python中没有方法重载,定义多个同名函数之后最后定义的那个会生效

3. 方法的动态性

动态地修改方法

class Person:
	def work(self):
		print("hard working")

def play_game(s):
	print("{0} is playing games".format(s))

Person.paly=play_game
P=Person()
print("id of P is {0}; id of Person class is {1}".format(id(P),id(Person)))
P.work()
P.paly()
############################output
id of P is 1987890177984; id of Person class is 1987882918672
hard working
<__main__.Person object at 0x000001CED77CE7C0> is playing games

4. 装饰器@property

@property可以将一个方法的调用方式编程属性调用

get,set访问用以访问和设置私有属性

class Employee:
	def __init__(self,name,salary):
		self.name = name   
		self.__salary = salary  

	def get_salary(self):
		return self.__salary

	def set_salary(self,a):
		if 1000<a<10000:
			self.__salary=a
			return self.__salary
		else:
			raise ValueError  

emp1=Employee("Jing", 2000)
print(emp1._Employee__salary) ##访问私有属性的方式一
emp1.get_salary() ##通过实例方法访问私有属性
emp1.set_salary(5000)
emp1.get_salary()

试用@property装饰器的方法

class Employee:
	def __init__(self,name,salary):
		self.name = name   
		self.__salary = salary  
	@property
	def salary(self):
		return self.__salary
	@salary.setter
	def salary(self,a):
		if 1000<a<10000:
			self.__salary = a
			return self.__salary
		else:
			raise ValueError 

emp1=Employee("Jing", 2000)
print(emp1._Employee__salary) ##访问私有属性的方式一
emp1.salary ##通过实例方法访问私有属性
emp1.salary= 5000 
emp1.salary

类的继承

继承是代码复用的重要手段,子类(派生类)继承了父类(基类)的属性和方法.

  • 父类.__init__() 来继承父类的构造方法
  • 也可以在子类中添加自己的属性和方法
## 类的继承

class Person:
	def __init__(self,name,age,gender):
		self.name =  name
		self.age = age
		self.__gender = gender
	
	@property
	def gender(self):
		return self.__gender
	@gender.setter
	def gender(self,a):
		self.__gender = a 
		print(self.__gender)
		return self.__gender

class Student(Person):
	def __init__(self,name,age,gender,score):
		Person.__init__(self, name, age, gender) ##这里调用父类构造函数需要用显示方法,用super会报错
		self.score = score
	def study():
		print("study hard")

S1=Student('Jing', 18, 'formale',80)
print(S1.gender)
S1.gender='male'

1. 类成员的继承和重写

在子类中对父类已经出现的方法重新定义,则调用子类重命名之后的方法

2. 重写__str__()方法

str()方法用来打印信息

class Student:
	def __init__(self,name,major):
		self.name = name  
		self.__major= major  

S = Student('Jing', "Chem")
print(S)
##输出<__main__.Student object at 0x000001E1507BE7C0>

## 重写__str__()方法
class Student:
	def __init__(self,name,major):
		self.name = name  
		self.__major= major  
	def __str__(self):
		return("{0}'s major is {1}".format(self.name,self.__major))

S = Student('Jing', "Chem")
print(S)
##输出Jing's major is Chem

3. 查看类的继承层次结构

通过类的方法 mro() 或者 __mro__ 属性

dir()查看对象属性

4. 多重继承

python中一个子类可以有多个直接的父类,这样也就具备了多个父类的特点,但是这样会被类的整体层次搞得异常复杂,尽量避免试用

5. super()获得父类定义

在定义子类时可以用super()函数调用父类的方法

## super()获取父类的定义

class A:
	def say(self):
		print("A:",self)

class B(A):
	def say(self):
		# A.say(self)
		super().say()
		print("B:",self)

B().say()
####输出
# A: <__main__.B object at 0x0000019A4C44E310>
# B: <__main__.B object at 0x0000019A4C44E310>

6. MRO()

Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序进行

MRO: Method Resolution Order

## MRO规则

class A:
	def aa(self):
		print("aa")

class B:
	def aa(self):
		print("bb")

class C(B,A):
	pass

c=C()
c.aa()
##输出 bb

多态

多态(polymorphism)指同一个方法调用用于不同对象可能会产生不同的行为

  1. 多态是方法的多态,属性没有多态
  2. 多态的存在有2个必要条件:继承、方法重写
## 多态
class Man:
	def eat(self):
		print("饿了,吃饭啦!")  

class Chinese(Man):
	def eat(self):
		print("中国人用筷子吃饭")

class English(Man):
	def est(self):
		print("英国人用叉子吃饭")

class Indian(Man):
	def eat(self):
		print('印度人用右手吃饭')

def manEat(m):
	if isinstance(m,Man):
		m.eat()
	else:
		print("不用吃饭")

manEat(Chinese()) ##中国人用筷子吃饭
manEat(Indian()) ##印度人用右手吃饭
manEat(Man()) ##饿了,吃饭啦!

1. 特殊方法和运算符重载

Python中的运算符实际上是通过调用对象的特殊方法实现的,比如“+” 是调用__add__,见下表

在这里插入图片描述

还有其他的一些特殊方法

在这里插入图片描述

  • 重新定义一个加法
##自定义加法

class Person:
	def __init__(self,name,family_name):
		self.name = name  
		self.family_name = family_name
	def __add__(self,other):
		if isinstance(other, Person):
			return "{0}---{1}".format(self.name,other.name)
		else:
			raise TypeError("不同类型不能相加")

p1=Person("Jing", 'Yu')
p2=Person('Gao', 'Qi')
p3=1
print(p1+p2) ##输出 Jing---Gao
#print(p1+p3)  ##输出TypeError: 不同类型不能相加

3. 组合

组合是一种可以实现类方法复用的计数,是继承的一种替代方法

##测试组合
class A1:
	def say_a1(self):
		print("a1,a1,a1")

class B1(A1):
	pass

b1=B1()
b1.say_a1()

## 同样地,可以用组合实现代码的复用
class A2:
	def say_a2(self):
		print('a2,a2,a2')

class B2:
	def __init__(self,a):
		self.a = a  
a2 = A2()		
b2=B2(a2)
b2.a.say_a2()  ## 输出  a2, a2, a2

3. 特殊属性

Python对象中包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊的用法,实例:

在这里插入图片描述

设计模式

设计模式是面向对象语言特有的内容,是我们在面临一类问题是固定的做法,设计模式有很多种,比较流行的是GOF23种设计模式,当然,我们没有必要全部学习,学习几个常用的极客

最常用的两个模式:工厂模式,单例模式

  • 工厂模式实现了创建者和调用者的分离,试用专门的工厂类将选择实现类、创建对象进行统一的管理和控制
  • 单例模式的核心作用是确保i各类只有一个实例,并且提供访问一个访问该实例的全局访问点。减少开销
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值