类方法和静态方法
类中方法分为:对象方法、类方法和静态方法
-
对象方法
怎么定义: 直接定义在类中的函数
怎么调用: 用对象来调用 -> 对象.对象方法()
特点: 自带参数self;self调用的时候不用传参,指向当前对象(谁调用指向谁)
什么时候用: 如果实现函数的功能,需要用到对象属性,就将这个函数定义成对象方法用对象调用对象方法,也叫给这个对象发一个消息
-
类方法
怎么定义: 在类中,定义函数前加@classmethod装饰器
怎么调用: 用类来调用 -> 类名.类方法()
特点: 自带参数cls;cls调用的时候不用传参,指向当前类(谁调用指向谁或者谁的类)
什么时候用: 实现函数的功能在不需要对象属性的前提下,需要类(类属性),就是用类方法 -
静态方法
怎么定义: 在类中,定义函数前加@staticmethod装饰器
怎么调用: 用类来调用 -> 类名.静态方法()
特点: 没有默认参数,相当于定义在类中的普通函数
什么时候用: 实现函数的功能不需要对象(对象属性)也不需要类(类属性)
class Dome:
num = 20
def func1(self):
pass
@classmethod
def func2(cls):
d2 = cls() # cls可以创建对象
print(cls.num) # cls使用类属性
pass
@staticmethod
def func3():
pass
# 使用类属性
print(Dome.num)
# 调用对象方法
d = Dome()
d.func1()
# 调用类方法
Dome.func2()
- 练习:用面向对象实现斗地主发牌的功能
import random
class Poker:
nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
colors = ['♣', '♥', '♠', '♦']
def __init__(self, num, color):
self.num = num
self.color = color
def __repr__(self):
return f'{self.color}{self.num}'
@classmethod
def a_deck_of_cards(cls):
pokers = [Poker(n, c) for n in cls.nums for c in cls.colors]
pokers.extend([Poker('Joker', ' '), Poker('joker', ' ')])
return pokers
class PokerGame:
def __init__(self):
# 一副牌
self.pokers = Poker.a_deck_of_cards()
# print(self.pokers)
def deal_cards(self):
random.shuffle(self.pokers)
# return self.pokers
"""
play_a = [x for x in self.pokers[0:51:3]]
play_b = [x for x in self.pokers[1:51:3]]
play_c = [x for x in self.pokers[2:51:3]]
landlord_card = [x for x in self.pokers[51::]]
return play_a, play_b, play_c, landlord_card
"""
# 把一副牌转化成迭代器
p = iter(self.pokers)
player1 = []
player2 = []
player3 = []
for _ in range(17):
player1.append(next(p))
player2.append(next(p))
player3.append(next(p))
player1.sort(key=PokerGame.key, reverse=True)
player2.sort(key=PokerGame.key, reverse=True)
player3.sort(key=PokerGame.key, reverse=True)
return player1, player2, player3, list(p)
@staticmethod
def key(item: Poker):
nums = {'Joker':17, 'joker':16, '2':15, 'A':14, 'K':13, 'Q':12, 'J':11}
num = item.num
return int(num) if '3' <= num <= '9' or num == '10' else nums[num]
game = PokerGame()
p1, p2, p3, d = game.deal_cards()
print(p1)
print(p2)
print(p3)
print('底牌:', d)
继承
-
什么是继承
让子类直接拥有父类的属性和方法的过程
子类: 继承者
父类: 被继承者 -
怎么继承
语法:
class 类名(父类列表):
类的内容
说明:
父类列表 - 父类1, 父类2, 父类3, …注意:
如果定义类的时候没有些继承关系,那么这个类默认继承自 object 类(object是python的基类,所有的类都直接或者间接的继承它) -
在子类中添加内容
在子类拥有父类的属性和方法的基础上添加属于自己特有的属性和方法
-
添加类属性和方法
直接在子类中定义新的类属性和新的方法 -
添加对象属性
对象属性是通过继承父类的__init__方法而继承到的
-
-
类和对象调用方法的顺序:
先看当前类中有没有对应的方法,如果没有看父类中有没有,如果父类没有就看父类的父类,…以此类推,直到找到object都没有的时候才报错
class C: num = 100 def __init__(self, a): print('C中的init方法') self.a = a self.b = 20 @classmethod def func1(cls): print('C中的类方法') class D(C): count = 10 def __init__(self): super().__init__(999) # 调用当前类的父类的__init__方法 print('D中的init方法') self.c = 888 def func2(self): print('D中的对象方法') @classmethod def func3(cls): print('D中的类方法') print(D.num, D.count) D.func1() d = D() d.func2() D.func3() print(d.a, d.b)
重写
重写:在子类中重新定义父类中的方法
class A:
def func1(self):
print('A中的func1')
class B(A):
def func1(self):
super().func1()
print('B中的func1')
def func2(self):
pass
a = A()
b = B()
b.func1()
a.func1()
运算符重载
-
在python中使用运算符的本质
在python中同一个运算符在面对不同类型的数据的时候,功能可以完全不一样
python中在使用运算符的时候,其实是在通过数据去调用这个运算符对应的魔法方法
在python中每一个运算符都对应一个名字固定的魔法方法,指定类型的数据是否支持某种运算符,就看这个类中有没有实现这个运算符对应的魔法方法
from copy import copy
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
# self指向+前面的数据,other指向+后面的数据
# 返回值: 运算结果
def __add__(self, other):
return self.score + other.score
def __mul__(self, other):
return [copy(self) for _ in range(other)]
def __repr__(self):
return f'<{str(self.__dict__)[1:-1]}, _id:{id(self)}>'
# 注意: 大于和小于对应的方法只需要写一个,另外一个直接执行
def __lt__(self, other):
return self.score < other.score
stu1 = Student('小花', 18, 90)
stu2 = Student('小明', 19, 80)
stu3 = Student('小红', 20, 70)
print(stu1 + stu3) # stu1.__add__(stu2)
print(stu1 * 3)
students = [stu1, stu2, stu3]
students.sort()
print(students)
对象属性的增删改查
class Student:
def __init__(self, name, age=18, gender='男'):
self.name = name
self.age = age
self.gender = gender
stu1 = Student('小明')
stu2 = Student('张三')
-
获取对象属性
对象.属性名
print(stu1.name) # print(stu1.height) - AttributeError 属性不存在会报错! # getattr(对象, 属性名) print(getattr(stu1, 'name')) # print(getattr(stu1, 'height')) - 报错! print(getattr(stu1, 'height', 180)) # 返回180 x = 'age' print(getattr(stu1, x))
-
增改
-
对象.属性名 = 值
stu1.name = '小花' print(stu1.name) # 属性存在会修改,没有会增加 stu1.weight = 120 print(stu1.weight)
-
setattr(对象, 属性名, 值)
setattr(stu1, 'age', 20) print(stu1.age) # 20 setattr(stu1, 'score', 100) print(stu1.score) # 100
-
删
-
del 对象.属性
del stu1.age # print(stu1.age) - AttributeError 报错!
-
delattr(对象, 属性名)
delattr(stu1, 'name') # print(stu1.name) - AttributeError 报错!
-
-