Python面向对象编程&SOLID设计原则&设计模式

先看看整体的提纲:

例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()

你可能感兴趣的:(人生苦短,我用Python,python)