文章目录
方法没有重载
方法的动态性
Python是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有方法。
class Person:
def work(self):
print("努力上班!")
def play_game(s):
print("{0}在玩游戏".format((s)))
Person.play = play_game;
p = Person()
p.work()
p.play()
努力上班!
<__main__.Person object at 0x0000018C49F85808>在玩游戏
私有属性和私有方法(实现封装)
私有属性
class Employee:
def __init__(self,name,age):
self.name = name
self.__age = age
e = Employee("Man",18)
print(e.name)
print(e._Employee__age)
Man
18
私有方法
class Employee:
def __init__(self,name,age):
self.name = name
self.__age = age
def __work(self):
print("好好工作")
e = Employee("Man",18)
print(e.name)
print(e._Employee__age)
print(dir(e))
e._Employee__work()
Man
18
['_Employee__age', '_Employee__work', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']
好好工作
property装饰器
可以将一个方法的调用方式变成属性调用。
class Employee:
@property
def salary(self):
print("salary ran")
return 100
emp1 = Employee()
print(emp1.salary)
salary ran
100
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,salary):
if 1000<salary<50000:
self.__salary = salary
else:
print("录入错误")
emp1 = Employee("Man",30000)
print(emp1.get_salary())
emp1.set_salary(-200000)
print(emp1.get_salary())
30000
录入错误
30000
面向对象三大特征介绍
- 封装(隐藏)
- 继承
- 多态
继承
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def say_age(self):
print("年龄,我也不知道")
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #必须显式的调用父类初始化方法,不然解释器不回去调用
self.score = score
print(Student.mro())
s = Student("Man",18,60)
s.say_age()
print(s.name)
print(dir(s))
print(s._Person__age)
[<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]
年龄,我也不知道
Man
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'say_age', 'score']
18
类成员的继承和重写
- 成员继承:子类继承了父类除构造方法之外的所有成员。
- 方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def say_age(self):
print("我的年龄:",self.__age)
def say_intro(self):
print("我的名字是{0}".format(self.name))
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #必须显式的调用父类初始化方法,不然解释器不回去调用
self.score = score
def say_intro(self):
print("报告老师,我的名字是{0}".format(self.name))
s = Student("Man",18,80)
s.say_age()
s.say_intro()
我的年龄: 18
报告老师,我的名字是Man
查看类的继承层次结构
通过类的方法mro()或者类的属性__mro__可以输出这个类的继承层次结构
object根类
object类是所有类的父类,因此所有的类都有object类的属性和方法。
dir()查看对象属性
重写__str__()方法
class Person:
def __init__(self,name):
self.name = name
def __str__(self):
return "名字是{0}".format(self.name)
p = Person("Man")
print(p)
名字是Man
多重继承
一个子类可以有多个“直接父类”。
MRO()
如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序搜索
class A:
def aa(self):
print("aa")
def say(self):
print("say AAA!")
class B:
def bb(self):
print("bb")
def say(self):
print("say BBB!")
class C(B,A):
def cc(self):
print("cc")
c = C()
print(C.mro())
c.say()
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
say BBB!
super()获取父类定义
在子类中,如果想要获得父类的方法时,super()代表父类的定义,不是父类对象。
多态
class Man:
def eat(self):
print("饿了,吃饭了")
class Chinese(Man):
def eat(self):
print("中国人用筷子吃饭")
class English(Man):
def eat(self):
print("英国人用叉子吃饭")
class Indian(Man):
def eat(self):
print("印度人用右手吃饭")
def manEat(m):
if isinstance(m,Man):
m.eat()
else:
print("不能吃饭")
manEat(Chinese())
中国人用筷子吃饭
特殊方法和运算符重载
class Person:
def __init__(self,name):
self.name = name
def __add__(self, other):
if isinstance(other,Person):
return "{0}-{1}".format(self.name,other.name)
else:
return "不是同类对象,不能相加"
def __mul__(self, other):
if isinstance(other,int):
return self.name+other
else:
return "不是同类对象,不能相乘"
p1 = Person("Man")
p2 = Person("Ann")
x = p1+p2
print(x)
print(x*3)
Man-Ann
Man-AnnMan-AnnMan-Ann
特殊属性
对象的浅拷贝和深拷贝
-
变量的赋值操作
只是形成两个变量,实际还是指向同一个对象。 -
浅拷贝
拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。因此,原对象和拷贝对象会引用同一个子对象。 -
深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象。原对象和拷贝对象所有的子对象也不同。
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self):
print("算你个")
print("cpu对象",self)
class Screen:
def show(self):
print("显示一个好看的画面,亮瞎你的钛合金大眼")
print("screen对象",self)
#测试变量赋值
c1 = CPU()
c2 = c1
print(c1)
print(c2)
#测试浅拷贝
s1 = Screen()
m1 = MobilePhone(c1,s1)
m2 = copy.copy(m1)
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
<__main__.CPU object at 0x0000014913865F08>
<__main__.CPU object at 0x0000014913865F08>
<__main__.MobilePhone object at 0x0000014913865F88> <__main__.CPU object at 0x0000014913865F08> <__main__.Screen object at 0x0000014913865F48>
<__main__.MobilePhone object at 0x0000014913876B48> <__main__.CPU object at 0x
组合
#使用继承实现代码复用
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()
a1,a1,a1
a2,a2,a2
设计模式
工厂设计模式
class CarFactory:
def create_car(self,brand):
if brand == "奔驰":
return Benz()
elif brand == "宝马":
return BMW()
elif brand == "比亚迪":
return BYD()
else:
return "未知品牌,无法创建"
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory = CarFactory()
c1 = factory.create_car("奔驰")
c2 = factory.create_car("比亚迪")
print(c1)
print(c2)
<__main__.Benz object at 0x0000024BA3AE5D08>
<__main__.BYD object at 0x0000024BA3AE5D48>
单例模式实现
单例模式的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较多的资源,如配置文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久驻留内存中,从而极大地降低开销。
class MySingleton:
__obj = None
__init_flag = True
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
if MySingleton.__init_flag:
print("init...")
self.name = name
MySingleton.__init_flag = False
a = MySingleton("aa")
b = MySingleton("bb")
print(a)
print(b)
c = MySingleton("cc")
print(c)
init...
<__main__.MySingleton object at 0x0000023609845AC8>
<__main__.MySingleton object at 0x0000023609845AC8>
<__main__.MySingleton object at 0x0000023609845AC8>