类进阶
受苦的人,没有悲观的权力 – 尼采
类属性和类方法
之前对象属性和对象方法是绑定在对象这个层次上的,也就是说需要先创建对象,然后才能使用对象的属性和方法
对象 = 类()
对象.属性
对象.方法()
除此之外,还有一种绑定在类这个层面的属性和方法,叫做类属性和类方法.使用类属性和类方法,不用创建对象,直接通过类来使用
类属性和类方法的使用方式:
类.属性
类.方法()
类属性的定义
- 只要将属性定义在类之中方法之外即可
class Char:
属性2 = 值
def 某方法():
pass
- 举个例子
class Char:
letters = 'ABCDEFG'
digits = '0123456789'
这里定义了类 Char 有两个类属性,这两个类属性分别包含所有大写字母和所有数字.可以通过类名来使用这两个类属性,无须创建对象
class Char:
letters = 'ABCDEFG'
digits = '0123456789'
print(Char.letters)
print(Char.digits)
# 结果
# ABCDEFG
# 0123456789
类方法的定义
定义类方法时,需要在方法前面加上装饰器,装饰器以后会说明现在只要知道用法即可
class 类:
@classmethod
def 类方法(cls):
pass
类方法的第一个参数通常名为 cls,表示当前这个类本身.我们可以通过该参数来引用类属性,或者类中其他类方法
类方法中可以使用该类的类属性,但不能使用该类的对象属性.因为类方法属于类,而对象属性属于对象,使用类方法的时候可能对象还没有被创建出来
- 举例子
import random
class Char:
letters = 'ABCDEFG'
digits = '0123456789'
@classmethod
def random_letter(cls):
return random.choice(cls.letters)
@classmethod
def random_digits(cls):
return random.choice(cls.digits)
result1 = Char.random_letter()
result2 = Char.random_digits()
print(result1)
print(result2)
# 结果 随机
# F
# 3
静态方法
与类方法有点相似的是静态方法,静态方法也可以直接通过类名来调用,不必创建对象.不同在于类方法的第一个参数是类自身(cls) 而静态方法没有这样的参数.
如果方法需要和其他类属性或者类方法交互,那么可以将其定义为类方法.如果方法无需和其他类属性或者类方法交互,那么可以将其定义成静态方法
定义静态方法时候,需要在方法的前面加上装饰器@staticmethod
class 类:
@staticmethod
def 静态方法():
pass
- 举例
import random
class Char:
letters = 'ABCDEFG'
digits = '0123456789'
@classmethod
def random_letter(cls):
return random.choice(cls.letters)
@staticmethod
def random_char(string):
if not isinstance(string, str):
raise TypeError('需要传递字符参数')
return random.choice(string)
result1 = Char.random_letter()
result2 = Char.random_char('哈黑白')
print(result1)
print(result2)
# 结果
# G 白
私有属性和方法
有的时候我们不希望把信息暴露除去,只希望在类中使用,不能被类的外部所访问
我们可以在属性或者方法的名称上用__(两个下划线)开头即可
import random
class Char:
__letters = 'ABCDEFG'
__digits = '0123456789'
@classmethod
def random_letter(cls):
return random.choice(cls.__letters)
@staticmethod
def random_char(string):
if not isinstance(string, str):
raise TypeError('需要传递字符参数')
return random.choice(string)
result1 = Char.__digits
result2 = Char.__letters
print(result1)
print(result2)
# 结果就直接报错了
- 可是类中的方法却能直接使用
import random
class Char:
__letters = 'ABCDEFG'
__digits = '0123456789'
@classmethod
def random_letter(cls):
return random.choice(cls.__letters)
@staticmethod
def random_char(string):
if not isinstance(string, str):
raise TypeError('需要传递字符参数')
return random.choice(string)
# result1 = Char.__digits
# result2 = Char.__letters
# print(result1)
# print(result2)
result3 = Char.random_letter()
print(result3)
像这样以__(两个下划线)开头的属性,我们称为私有属性.顾名思义它是私有的,不能在类的外部使用
特殊方法
类中以__开头并以__结尾的方法是特殊的方法,特殊的方法有特殊的用途,他们可以直接调用,也可以通过一些内置函数或操作符来间接调用,如__init__(),__next__()
特殊方法有很多,我们简单说几个
(1) __init__()
init 是一个非常典型的特殊方法,它用于对象的初始化,在实例化类的过程中被自动调用
(2)__next__()
next() 在迭代器中表示能生成下一个值.
(3) __len__()
len 函数就是获取容器的长度
(4) __str__()
在使用 print()函数将自动调用 str 方法
class A:
def __str__(self):
return '这是A的对象'
(5) __getitem__()
诸如列表,元素,字符串这样的序列,我们可以通过索引的凡是来获取其中的元素,这背后 getitem()起作用
'abc'.__getitem__(2)
## 结果 c
继承
如果想基于一个现有的类获取其全部能力,并在此基础上获取一个更强大的类。此时应该使用类的继承.被继承的类叫做父类,继承者叫做子类
class 父类:
父类的实现
class 子类(父类):
子类的实现
- 例如
class A :
def __init__(self):
self.apple = 'apple'
def haveapple(self):
print('hava' ,self.apple)
class B(A):
def who(self):
print('这就是子类')
b = B()
b.who() # 这就是子类
b.haveapple() # have apple
b.apple # apple
子类 B 当中也可以自己定义自己的属性
class B(A):
def __init__(self):
super().__init__()
self.banana = 'banana'
b =B()
b.banana # 结果banana
我们在 B 中定义了 init 方法并在其中定义了 B 自己的属性 banana
super().__init__()这句代码的意思就是子类初始化的同时初始化父类
super()用在类的方法中时,返回父类对象
- 子类要是出现和父类同名的方法的话,子类会覆盖父类的同名方法
class A:
def __init__(self):
self.apple = 'apple'
def have(self):
print('I hava an', self.apple)
class B(A):
def __init__(self):
super().__init__()
self.banana = 'banana'
def have(self):
print('I hava an', self.banana)
b = B()
b.have() # 结果 I have an banana
继承链
子类可继承父类,同样的父类也可以继承自己的父类,如此一层一层继承下去
class A:
def have(self):
print('I hava an apple')
class B(A):
pass
class C(B):
pass
c = C()
c.have() # I have an apple
- 如果要判断一个类是否是另一个类的子类,可使用内置函数 issubclass()
issubclass(C,A)
# True
issubclass(B,A)
# True
issubclass(C,B)
# True
多继承
子类可以同时继承多个父类
定义时子类后面加上括号并写人多个父类
class A:
def get_apple(self):
return 'apple'
class B:
def get_banana(self):
return 'banana'
class C(A, B):
pass
C= C()
c.get_apple()
c.get_banana()
# C 同时具有了A,和B的能力