1.类和实例
class Student(object):
score = 100 # 类的属性
__math = 10 # 类的私有属性
# 限制实例能添加的属性
__slots__ = ['name', '_age', '__sex']
def __init__(self, name, age, sex):
self.name = name
self._age = age # 约定的私有属性
self.__sex = sex # 私有属性
# 约定的私有方法
def _getage(self):
print("age: ", self._age)
# 私有方法
def __getsex(self):
print('sex: ', self.__sex)
# 静态方法
@staticmethod
def func1():
print('staticmethod');
# 类方法
@classmethod
def func2(cls, name, age, sex):
print(cls.score)
cls(name, age, sex).func1()
s = Student('aya', 18, 'girl')
# 属性访问
print(s.score, s._Student__math)
print(s.name, s._age, s._Student__sex)
# 实例方法调用
s._getage()
s._Student__getsex()
# 静态方法调用
s.func1()
Student.func1()
# 类方法调用
Student.func2('aya', 18, 'girl')
print(Student.__dict__) # 类的属性字典
print(Student.__doc__) # 类的文档
print(Student.__name__) # 类名
print(Student.__module__) # 类定义所在模块
print(Student.__bases__) # 类的所有父类
2.property
# property装饰器将方法变成属性
class Student(object):
def __init__(self, birth):
self._birth = birth
# birth是可读写属性
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
@birth.deleter
def birth(self):
print("删除属性")
del self._birth
# age是只读属性
@property
def age(self):
return 2020 - self._birth
s = Student(2000)
print(s.birth) # 2000
s.birth = 2002
print(s.birth) # 2002
print(s.age) # 18
del s.birth
3.继承
单继承
class Student(object):
def __init__(self, name):
self.name = name
def get_name(self):
print("Student", self.name)
class Girl(Student):
def __init__(self, name):
super().__init__(name)
self.sex = 'Girl'
def get_name(self):
super().get_name()
print(self.sex, self.name)
g = Girl('Alice')
g.get_name()
# Student Alice
# Girl Alice
多继承
class Base:
def __init__(self):
print('Base.__init__')
class A(Base):
def __init__(self):
super().__init__()
print('A.__init__')
class B(Base):
def __init__(self):
super().__init__()
print('B.__init__')
class C(A,B):
def __init__(self):
super().__init__()
print('C.__init__')
c = C()
# Base.__init__
# B.__init__
# A.__init__
# C.__init__
C.__mro__ # 所有基类的线性顺序表
# (__main__.C, __main__.A, __main__.B, __main__.Base, object)
4.运算符重载
常用运算符
class Vector(object):
def __init__(self, x, y):
self.x = x
self.y = y
# print()时显示的内容
def __str__(self):
return 'Vector(%r, %r)' % (self.x, self.y)
__repr__ = __str__
# 重载加号运算符
# 类似的:sub mul div mod pow
def __add__(self, other):
return Vector(self.x+other.x, self.y+other.y)
# 直接调用实例自身
def __call__(self):
print('Called by myself!')
v1 = Vector(1, 1)
print(v1) # Vector(1, 1)
v2 = Vector(2, 2)
print(v1 + v2) # Vector(3, 3)
v2() # Called by myself!
下标运算符
# 自定义一个只能存放int类型的list
class IntList(object):
def __init__(self, *args):
if all(map(lambda x:isinstance(x, int), args)):
self._list = list(args)
else:
print("所有传入的参数必须是整数!")
def __getitem__(self, index):
return self._list[index]
def __setitem__(self, index, value):
self._list[index] = value
def __delitem__(self, index):
del self._list[index]
def __len__(self):
print("调用__len__方法")
return len(self._list)
l = IntList(1,2,3,4,5)
print(len(l))
# 调用__len__方法
# 5
print(l[0]) # 1
l[0] = -1
print(l[0]) # -1
del l[0]
print(l[0]) # 2
5.元类
#1 type()动态创建类
def myfunc(self, name='Tom'):
print('Hello, %s!' % self.name)
# 参数分别为:class名称、继承的父类集合、方法名称与函数绑定
Student = type('Student', (object,), dict(name='Jack', func=myfunc))
s = Student()
s.func() # Hello, Jack!
#2 metaclass元类
class ListMetaclass(type):
def __new__(cls, name, bases, attrs):
# 为类动态添加属性
attrs['doc'] = 'A metaclass!'
# 为类动态添加方法
attrs['add'] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs)
# 使用ListMetaclass来定制类
class MyList(list, metaclass=ListMetaclass):
pass
L = MyList()
L.add(1)
print(L) # [1]
print(L.doc) # A metaclass!
6.单例模式
class Singleton(object):
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
Singleton._instance = object.__new__(cls)
return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(id(obj1) == id(obj2)) # True