例1:
class Kls2():
def __init__(self,fname,lname):
self.fname = fname
self.lname = lname
def print_name(self):
print (f'first name is {self.fname},last name is {self.lname}')
me = Kls2('wilson','yin')
me.print_name()
# 如果传出 wilson-yin 改怎么解决?
# 这里我们看看解决思路,以及使用类方法优化
def pre_name(obj,name):# 一起皆对象,类也是对象
fname,lname = name.split('-')
return obj(fname,lname)
me2 = pre_name(Kls2,'wilson-yin')
me2.print_name()
## 写入类方法
class Kls2:
def __init__(self,fname,lname):
self.fname = fname
self.lname = lname
def print_name(self):
print (f'first name is {self.fname},last name is {self.lname}')
@classmethod
def pre_name(cls,name):
fname,lname = name.split('-')
return cls(fname,lname)
me3 = Kls2.pre_name('wilson-yin')
me3.print_name()
例2:
## 继承类方法
class Fruit(object):
total = 0
@classmethod
def print_total(cls):
print (cls.total)
print (id(Fruit.total))
print (id(cls.total))
@classmethod
def set(cls,value):
print (f'calling {cls},{value}')
cls.total = value
class Apple(Fruit):
pass
class Orange(Fruit):
pass
Apple.set(100)
#calling ,100
Orange.set(200)
# calling ,200
org = Orange().set(300)
#calling ,300
Apple.print_total()
# 100
# 140717321678560
# 140717321681760
Orange.print_total()
# 300
# 140717321678560
# 2327852668752
例3:
# __getattribute__ 对属性拦截、修改
class Human2(object):
def __init__(self):
self.age = 18
def __getattribute__(self, item):
print (f'__getattribute__ called item:{item}')
try:
return super().__getattribute__(item)
except Exception as e:
self.__dict__[item] = 100
return 100
h1 = Human2()
print(h1.age)
print(h1.noattr)
例4:
# __getattr__
class Human2(object):
def __init__(self):
self.age = 18
def __getattr__(self, item):
print (f'__getattr__ called item:{item}')
# 不存在的属性返回默认值‘OK’
return "ok"
h1 = Human2()
print(h1.age)
print(h1.noattr)
class Human2(object):
def __init__(self):
self.age = 18
def __getattr__(self, item):
# 对指定属性做处理
self.item = item
if self.item == 'fly':
return 'supperman'
h1 = Human2()
print (h1.age)
print (h1.fly)
print (h1.noattr)
例5:
# 如果同时存在,执行顺序是 __getattribute__>__getattr__>__dict__
class Human2(object):
def __init__(self):
self.age = 18
def __getattr__(self, item):
print ('Human2:__getattr__')
return 'Err 404,你请求的参数不存在'
def __getattribute__(self, item):
print('Human2:__getattribute__')
return super().__getattribute__(item)
h1 = Human2()
print (h1.age)
print (h1.noattr)
例6:
# __getattribute__的底层原理是描述器
class Desc(object):
"""
通过打印来展示描述器的访问流程
"""
def __init__(self,name):
self.name = name
def __get__(self,instance,owner):
print(f'__get__{instance}{owner}')
return self.name
def __set__(self, instance, value):
print(f'__set__{instance}{value}')
self.name = value
def __delete__(self, instance):
print (f'__delete__{instance}')
del self.name
class MyObj(object):
a = Desc('AAA')
b = Desc('bbb')
my_object = MyObj()
print (my_object.a)
my_object.a = 256
print (my_object.a)
例7:
# property的用法
class Human2(object):
def __int__(self):
self._gender = None
# 将方法封装成属性
@property
def gender2(self):
print (self._gender)
# 支持修改
@gender2.setter
def gender2(self,value):
self._gender = value
# 支持删除
@gender2.deleter
def gender2(self):
del self._gender
h = Human2()
h.gender2 = 'F'
h.gender2
del h.gender2
# 另一种写法gender = property(get_,set_,del_,'other property')
例8:
## 类
class People(object):
def __init__(self,name):
self.gene = 'XY'
self.name = name
def walk(self):
print ('I can walk')
class Man(People):
def __init__(self,name):
super().__init__(name)
def work(self):
print ('work hard')
class Woman(People):
def __init__(self,name):
super().__init__(name)
def shopping(self):
print('buy buy buy')
p1 = Man('adam')
p2 = Woman('eve')
print(p1.gene)
# object 和 type的关系
print ('object',object.__class__,object.__bases__)
print ('type',type.__class__,type.__bases__)
例9:
# 钻石继承
class BaseClass(object):
num_base_calls = 0
def call_me(self):
print ('Calling method on Base Class')
self.num_base_calls += 1
class LeftSubClass(BaseClass):
num_left_calls = 0
def call_me(self):
print ('calling method on left class')
self.num_left_calls += 1
class RightSubClass(object):
num_right_calls = 0
# def call_me(self):
# print ('calling method on right class')
# self.num_right_calls += 1
class SubClass(LeftSubClass,RightSubClass):
pass
a = SubClass()
a.call_me()
# 广度优先,另外python3中不加(object)也是新式类,但是未来代码不会误运行在python2下产生意外结果,仍然建议加(object)
print (SubClass.mro())
例10:
# 装饰器实现单实例
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass(object):
pass
m1 = MyClass()
m2 = MyClass()
print (id(m1))
print (id(m2))
# __new__与__init__的关系
class Foo(object):
def __new__(cls, name):
print ('trace __new__')
return super().__new__(cls)
def __init__(self,name):
print ('trace __init__')
super().__init__()
self.name = name
bar = Foo('test')
bar.name
# 利用__new__实现单例模式
# 利用模块是实现单例模式
例11:
# 工厂模式
class Human3(object):
def __init__(self):
self.name = None
self.gender = None
def getName(self):
return self.name
def getGender(self):
return self.gender
class Man(Human3):
def __init__(self,name):
print (f'Hi,man {name}')
class Woman(Human3):
def __init__(self,name):
print (f'Hi,woman {name}')
class Factory:
def getPerson(self,name,gender):
if gender == 'M':
return Man(name)
elif gender == 'F':
return Woman(name)
else:
pass
factory = Factory()
person = factory.getPerson('Adam','M')
例12:
# 返回在函数内动态创建的类
def factory2(func):
class K2:pass
# setattra需要三个参数:对象、key、value
setattr(K2,func.__name__,func)
return K2
def say_foo(self):
print ('bar')
Foo = factory2(say_foo)
foo = Foo()
foo.say_foo()
例13:
# 使用type元类创建类
def hi():
print ('Hi metaclass')
# type的三个参数:类名、父类的元组、类成员
F = type('F',(),{'say_hi':hi})
f = F
f.say_hi()
例14:
## 抽象基类
from abc import ABCMeta,abstractmethod
class Base(metaclass=ABCMeta):
@abstractmethod
def foo(self):
pass
@abstractmethod
def bar(self):
pass
class Concrete(Base):
def foo(self):
pass
c = Concrete()
例15:
# Mixin
def mixin(Klass,MixinKlass):
Klass.__bases__ = (MixinKlass,)+Klass.__bases__
class Fclass(object):
def text(self):
print ('in FatherClass')
class S1class(Fclass):
pass
class MixinClass(object):
def text(self):
return super().text()
class S2class(S1class,MixinClass):
pass
print (f'test1 :s1class mro:{S1class.mro()}')
s1 = S1class()
s1.text()
mixin(S1class,MixinClass)
print (f'test2:S1class mro:{S1class.mro()}')
s1 = S1class()
s1.text()
print (f'test3 :s2class mro:{S2class.mro()}')
s1 = S2class()
s1.text()