Python类Class的简单介绍,继承、静态方法和类方法、magic方法
1.继承
# -*-coding:utf-8 -*-
"""
在继承中,父类的构造方法(__init__()方法)不会自动调用,需要在子类的构造方法中专门调用
在调用父类的方法时需要加上父类的类名前缀,并带上 self 参数变量
在 Python 中,首先查找对应类型的方法,如果在子类中找不到对应的方法,才到父类中去查找。若继承多个父类,则按先后顺序查找
"""
# 父类
class People:
# 定义基本属性
name = ''
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, name, weight):
self.name = name
self.__weight = weight
def speak(self):
print("【父类方法】我叫 %s, 体重是 %s 千克" % (self.name, self.__weight))
# 公共方法
def public_method(self):
print("我是父类的公共方法")
return self.name
# 私有方法
def __private_method(self):
print("我是父类的私有方法")
return self.name
# 继承
class Student(People):
grade = ''
def __init__(self, name, weight, grade):
# 调用父类的构造方法
People.__init__(self, name, weight)
self.grade = grade
# 复写父类speak方法
def speak(self):
print("【子类方法】我叫 %s, 我上 %s 年级" % (self.name, self.grade))
s = Student('小明', 40, 5)
s.speak() # 输出: 【子类方法】我叫 小明, 我上 5 年级
# s.public_method() # 输出:我是父类的公共方法
# s.__private_method() # 此句报错,子类实例无法访问父类中的私有方法
2.类方法和静态方法
# -*- utf-8 -*-
"""
Python继承
"""
class A:
@staticmethod # 静态方法,可以直接通过 类型.方法名访问
def static_method():
print("我是一个静态方法")
# @classmethod # 类方法,可以直接通过 类型.方法名访问
def class_method(cls):
print("我是一个类方法")
A.static_method()
# A.class_method()
# 若不用 @classmethod 修饰,则需要通过创建实例访问方法
a = A()
a.class_method()
3.Python类中的magic方法
# -*-coding:utf-8 -*-
"""
Python类中的一些magic方法介绍,可以通过复写这些方法,实现特殊的功能
"""
from array import array
import math
import sys
class Vector2d:
code = 'd'
def __init__(self, x, y):
print('当前函数名称:', sys._getframe().f_code.co_name) # 吃语句用于打印当前方法名称,用于观察magic方法调用顺序
self.__x = float(x) # 两个前导下划线,把属性标记为私有的
self.__y = float(y)
@property # @property装饰器把读值方法标记为特性, 只读
def x(self): # 读值方法与公开属性同名,都是x
print('当前函数名称:', sys._getframe().f_code.co_name)
return self.__x
@property
def y(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return self.__y
# 迭代
def __iter__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return (i for i in (self.x, self.y))
def __repr__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
class_name = type(self).__name__
return '{}({!r}, {!r})'.format(class_name, *self) # {!r} 类似于 %r
def __str__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return str(tuple(self))
def __bytes__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)) # ord返回对应的ASCII码
# equals, 必须要实现__hash__方法
def __eq__(self, other):
print('当前函数名称:', sys._getframe().f_code.co_name)
return tuple(self) == tuple(other)
def __hash__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return hash(self.x) ^ hash(self.y)
def __abs__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return math.hypot(self.x, self.y) # hypot() 返回欧几里德范数 sqrt(x*x + y*y)
def __bool__(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return bool(abs(self))
def angle(self):
print('当前函数名称:', sys._getframe().f_code.co_name)
return math.atan2(self.y, self.x) # atan2() 返回给定的 X 及 Y 坐标值的反正切值
def __format__(self, fmt_spec=''):
print('当前函数名称:', sys._getframe().f_code.co_name)
if fmt_spec.endswith('p'): # 如果格式代码以'p'结尾,使用极坐标,否则构建直角坐标
fmt_spec = fmt_spec[:-1]
coords = (abs(self), self.angle())
outer_fmt = '<{}, {}>'
else:
coords = self
outer_fmt = '({}, {})'
components = ((format(c, fmt_spec)) for c in coords)
return outer_fmt.format(*components)
if __name__ == '__main__':
v = Vector2d(2, 3)
# if v == (2, 3):
# pass
# print(abs(v))
# if v:
# print(True)
# print(v)
# str(v)
# type(v)
# print(type(v))
# print(v.x)
# v.x = 10
# print(v.x)
# set(v)
# print(bytes(v))
# print(format(v, '.3p'))
# print(format(v, '.3f'))
# print(abs(v))
# v.frombytes('1234')
# if v:
# pass