本系列博文基于廖雪峰老师的官网Python教程,笔者在大学期间已经阅读过廖老师的Python教程,教程相当不错,官网链接: 廖雪峰官方网站.请需要系统学习Python的小伙伴到廖老师官网学习,笔者的编程环境是Anaconda+Pycharm,Python版本:Python3.
1.定制类
# 1.__str__
class Employee(object):
def __init__(self, name):
self.name = name
print("打印一个实例:", Employee("Willard."))
# 使用__str__
class Employee(object):
def __init__(self, name):
self.name = name
def __str__(self):
return "Employee object (name:%s)" % self.name
print("使用__str__打印一个实例:", Employee("Willard"))
# 结果输出:
# 打印一个实例: <__main__.Employee object at 0x000001F057CEFBA8>
# 使用__str__打印一个实例: Employee object (name:Willard)
# 2.__iter__
# 一个类如果想被用于for...in循环,先实现一个__iter__方法,
# 该方法返回一个迭代对象,然后不断调用该对象的__next__()方法拿到下一个值,
# 直到遇到StopIteration错误时退出循环;
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > 100000:
raise StopIteration()
return self.a
print("Fib实例作用于for循环!")
for n in Fib():
print(n,end = " ")
# 结果输出:
# Fib实例作用于for循环!
# 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025
# 3.__getitem__
# 实现像list可以按照下标取出元素
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
f = Fib()
print("Fib[0]的值为:", f[0])
print("Fib[100]的值为:", f[100])
# 结果输出:
# Fib[0]的值为: 1
# Fib[100]的值为: 573147844013817084101
# 判断__getitem__()传入的参数是int还是slice切片
class Fib(object):
def __getitem__(self, n):
if isinstance(n, int):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice):
start = n.start
stop = n.stop
if start is None:
start = 0
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
f = Fib()
print("f[0:5]的值为:", f[0:5])
print("f[100:150]的值为:", f[100:102])
# 结果输出:
# f[0:5]的值为: [1, 1, 2, 3, 5]
# f[100:150]的值为: [573147844013817084101, 927372692193078999176]
# 4.__getattr__
# 当调用类的方法或属性时,如果不存在,则报错
class Employee(object):
def __init__(self, name):
self.name = name
employee1 = Employee("Willard")
print("employee1.name的值为:", employee1.name)
# print("employee1.salary的值为:", employee1.salary) # 会报错
# 写一个__getattr__()方法,动态返回一个属性
class Employee(object):
def __init__(self, name):
self.name = name
def __getattr__(self, attr):
if attr == "salary":
return 20000
employee2 = Employee("LinWenYu")
print("employee2.salary的值为:", employee2.salary)
# 结果输出:
# employee1.name的值为: Willard
# employee2.salary的值为: 20000
# 5.__call__
# a.一个对象实例可以有自己的属性和方法,当调用实例方法时,使用instance.method()调用;
# b.直接在实例本身调用,只需要定义一个__call__()方法,就可以直接对实例进行调用;
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def __call__(self):
print("This Employee's name is %s.\nThe salary of %s is %d." % (self.name, self.name, self.salary))
employee = Employee("LinWenYu", 20000)
employee()
# 结果输出:
# This Employee's name is LinWenYu.
# The salary of LinWenYu is 20000.
2.使用枚举类
# 定义常量其中一个方法:用大写变量通过整数定义
JAN = 1
FEB = 2
MAR = 3
# ...
NOV = 11
DEC = 12
# 为这样的枚举类型定义一个class类型,每个常量是class的一个唯一实例
from enum import Enum
Month = Enum("Month", ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
# 使用Month.Jan引用常量
for name, member in Month.__members__.items():
print(name, "=>", member, ",", member.value)
# 结果输出:
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
May => Month.May , 5
Jun => Month.Jun , 6
Jul => Month.Jul , 7
Aug => Month.Aug , 8
Sep => Month.Sep , 9
Oct => Month.Oct , 10
Nov => Month.Nov , 11
Dec => Month.Dec , 12
# 更精确控制枚举类型,从Enum派生出自定义类
from enum import Enum, unique
# unique装饰器,检查保证没有重复值
@unique
class Weekday(Enum):
Sun = 0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
# 访问枚举类型
day1 = Weekday.Mon
print("The value of Day1:", day1)
print("The value of Day1:", Weekday(1))
print("The value of Day2:", Weekday.Tue)
print("The value of Day2:", Weekday["Tue"])
print("The value of Weekday.Wed is:", Weekday.Wed.value)
print("------------------------------------------------")
# 遍历
for name, member in Weekday.__members__.items():
print(name, "=>", member)
print(name, ".value", "=>", member.value, "\n")
# 结果输出:
The value of Day1: Weekday.Mon
The value of Day1: Weekday.Mon
The value of Day2: Weekday.Tue
The value of Day2: Weekday.Tue
The value of Weekday.Wed is: 3
------------------------------------------------
Sun => Weekday.Sun
Sun .value => 0
Mon => Weekday.Mon
Mon .value => 1
Tue => Weekday.Tue
Tue .value => 2
Wed => Weekday.Wed
Wed .value => 3
Thu => Weekday.Thu
Thu .value => 4
Fri => Weekday.Fri
Fri .value => 5
Sat => Weekday.Sat
Sat .value => 6
3.使用元类
# 1.type()
# 定义一个welcome.py模块
"""
class Welcome(object):
def welcome(self, welcomeString = "FUXI Technology."):
print("Welcome to %s" % welcomeString)
"""
from welcome import Welcome
w = Welcome()
w.welcome()
print("Welcome的类型为:", type(Welcome))
print("w的类型为:", type(w))
print("-------------------------------------")
# 通过type()函数创建Welcome类
# 通过type()函数创建对象
# 参数1:class的名称;
# 参数2:继承的父类集合,只有一个父类的时候,需要在单元素后添加逗号;
# 参数3:class的方法名称和函数绑定,把函数fn绑定到方法名welcome上;
def fn(self, welcomeString = "FUXI Technology."):
print("Welcome to %s" % welcomeString)
Welcome = type("Welcome", (object,), dict(welcome = fn)) # 创建Welcome类
w = Welcome()
w.welcome()
print("Welcome的类型:", type(Welcome))
print("w的类型:", type(w))
# 结果输出:
Welcome to FUXI Technology.
Welcome的类型为: <class 'type'>
w的类型为: <class 'welcome.Welcome'>
-------------------------------------
Welcome to FUXI Technology.
Welcome的类型: <class 'type'>
w的类型: <class '__main__.Welcome'>
# 2.metaclass:元类
# 先定义metaclass,然后创建类,最后创建实例
# metaclass是类的模板,必须从type类型派生;
# __new__()方法接收到的参数:
# 1.当前准备创建的类的对象;
# 2.类的名字;
# 3.类继承的父类集合;
# 4.类的方法集合;
class ListMetaclass(type):
def __new__(cls, name, bases, attrs):
attrs["add"] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs)
# 定义类
class MyList(list, metaclass = ListMetaclass):
pass
# 测试MyList是否可以调用add()方法
L = MyList()
L.add(1)
print("L.add(1):", L)
# 结果输出:
# L.add(1): [1]