Python学习之旅 —— 基础篇(八)面向对象、有序字典、设计模式之单例模式

概述

  • 面向过程:根据业务逻辑从上到下写垒代码
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

对比示例:函数式变成和面向对象编程

连接数据库的增删改查

# 函数式编程
def slect(host, username, password, sql):
    pass


def create(host, username, password, database):
    pass


def remove(host, username, password, table):
    pass


def modify(host, username, password, nid):
    pass

# 调用函数
hostname = "db01.renrenche.com"
user = "admin"
pwd = "123"
slect(hostname, user, pwd, "select * from db1")
create(hostname, user, pwd, "db1")
remove(hostname, user, pwd, "table1")
modify(hostname, user, pwd, "id01")
# 面向对象编程
# 01 创建类
class SQLHeper:
    def slect(self, sql):
        print(self.hostname)
        print(sql)


    def create(self, database):
        pass

    def remove(self, table):
        pass

    def modify(self, nid):
        pass

# 02 创建对象
obj = SQLHeper()

# 03 定义公共参数
obj.hostname = "db01.renrenche.com"
obj.user = "admin"
obj.pwd = "123"

# 04 调用类的方法
obj.slect("select * from db1")
obj.create("db1")
obj.remove("table1")
obj.modify("id")

一、创建类和对象

面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

  类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

  对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可

 

二、面向对象的三大特性:

面向对象的三大特性是指:封装、继承和多态。

1、封装

引入__init__()方法:

# 01 创建类
class SQLHeper:
    def __init__(self, host, username, password):
        self.hostname = host
        self.user = username
        self.pwd = password

    def slect(self, sql):
        print(self.hostname)
        print(sql)

    def create(self, database):
        pass

    def remove(self, table):
        pass

    def modify(self, nid):
        pass

# 02 创建对象
obj1 = SQLHeper("test1.rrc.com", "admin01", "123", )
obj2 = SQLHeper("test2.rrc.com", "admin02", "456", )


# 03 调用类的方法
obj1.slect("select * from db1")
obj2.slect("select count(*) from db2")

 

不止可以封装普通参数,可以封装任何参数

# 类的对象可以封装任何参数
class c1:
    def __init__(self, name, obj):
        self.name = name
        self.obj1 = obj


class c2:
    def __init__(self, job, age):
        self.job = job
        self.age = age

    def show(self):
        print(self.job)


class c3:
    def __init__(self, aaa):
        self.abc = aaa


c2_obj = c2("IT", 18)
c1_obj = c1("Pesen", c2_obj)


print(c1_obj.obj1.age)

c3_obj = c3(c1_obj)

# 通过c3 调用c2的show方法
c3_obj.abc.obj1.show()
封装一个类

 

2、继承

继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

class Foo1:  # Foo1是Foo2的父类(基类)
    def show(self, name):
        print("F1.show", name)


class Foo2(Foo1):  # Foo2是Foo1的子类(派生类)
    def __init__(self, name):
        self.name = name

    def bar(self):
        print("bar")

    def show(self, name):
        print("F2.show", name)

obj = Foo2("aaa")
obj.bar()
obj.show("Pesen")  # 优先执行自己的方法

 

python有一个特殊的继承方式就是多继承

 

3. 多态(多种形态、多种类型)

# python
def
func(args): print(args) func(1) func("Pesen") func([0, 1, 2, 3, ])
# C#/java
def func(int arg):
    print(arg)

func(111)
func("Pesen")   # 报错
class A:
    pass

class B(A):
    pass

class C(A):
    pass

# arg参数:必须是A类型或A的子类型
def (A arg):
    print(arg)

obj1 = B()
obj2 = C()
obj3 = A()

func(obj)

 

 三、类成员(字段、方法、属性)

 

注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。

 

1、字段

字段包括普通字段和静态字段。

  • 普通字段:属于对象,在每个对象中都要保存一份
  • 静态字段:属于类,在内存中只保存一份
class Province:

    country = "China"  # 静态字段

    def __init__(self, name):
        self.name = name  # 普通字段

bj = Province("北京")

# 一般情况下,自己访问自己的字段
# 规则:
#   普通字段只能用对象访问
#   静态字段用类访问(万不得已的时候可以使用对象访问)
print(bj.name)
print(Province.country)
字段的定义和使用

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

 

2、方法

方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

  • 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
  • 类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls
  • 静态方法:由调用;无默认参数。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:Pengcheng Xie


class Province:

    country = "China"  # 静态字段

    def __init__(self, name):
         self.name = name  # 普通字段

    # 普通方法
    def show(self):
         print(self.name)

    # 类方法
    @classmethod
    def class_func(cls):
        print(cls.country)


    # 静态方法
    @staticmethod
    def show_1(args1, args2):
        print(args1, args2)


bj = Province("北京")
bj.show()  # 调用普通方法
Province.class_func() # 调用类方法
Province.show_1(**{"args1": 111, "args2": 222})  # 调用静态方法
方法的定义和调用

 

3、属性

Python中的属性其实是普通方法的变种。

class Pager:
    def __init__(self, all_count):
        self.all_count = all_count

    @property  # 属性
    def all_pager(self):
        a1, a2 = divmod(self.all_count, 10)
        if a2 == 0:
            return a1
        else:
            return a1 + 1

    @all_pager.setter  # 设置可编辑属性
    def all_pager(self, value):
        print(value)

    @all_pager.deleter
    def all_pager(self):
        print("del all_pager")

p = Pager(101)

ret = p.all_pager  # 定义属性后,可以通过字段的调用方式在使用方法
print(ret)

p.all_pager = 101001

del p.all_pager  # 增加删除属性后,方法可以被删除,不加xxx_deleter是不允许删除的
class Pager:
    def __init__(self, all_count):
        self.all_count = all_count

    def f1(self):
        a1, a2 = divmod(self.all_count, 10)
        if a2 == 0:
            return a1
        else:
            return a1 + 1

    def f2(self, value):
        print(value)

    def f3(self):
        print("del all_pager")

    foo = property(fget=f1, fset=f2, fdel=f3)  # 属性的另外一种使用方式


p = Pager(101)

ret = p.foo
print(ret)

p.foo = 101001

del p.foo
通过property方法构造属性

属性的调用,通俗说就是可以实现通过字段的形式来使用方法。

 

四、类成员修饰符

对于每一个类的成员而言都有两种形式:

  • 公有成员,在任何地方都能访问
  • 私有成员,只有在类的内部才能方法
# 修饰字段
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.__age = age   # 前面加两个"__",变成私有字段

    def f1(self):
        print(self.name)
        print(self.__age)


class Bar(Foo):

    @staticmethod
    def f2():

          # 继承不能调用私有字段
        try:
            print(__age)
        except Exception:
            print(name)

obj = Foo("alex", 18)
obj.f1()

print(obj.name)  # 外部可以调用公共字段
# print(obj.__age)  # 外部不能调用私有字段


obj1 = Bar.f2()

ps:非要访问私有属性的话,可以通过 对象._类__属性名

 

五、类的特殊成员

 

 

 

六、其他

1、有序字典

class MyDict(dict):
    def __init__(self):
        self.list = list()
        super(MyDict, self).__init__()

    def __setitem__(self, key, value):
        self.list.append(key)
        super(MyDict,self).__setitem__(key, value)

    def __str__(self):
        temp_list = list()
        for key in self.list:
            value = self.get(key)
            temp_list.append('"{key}": "{value}"'.format(key=key, value=value))

        temp_str = "{" + ",".join(temp_list) + "}"
        return temp_str

obj = MyDict()
obj["k1"] = 123
obj["k2"] = 456
print(obj)

 

2、设计模式——单例模式

class Foo:
    instance = None

    def __init__(self, name):
        self.name = name

    @classmethod
    def get_instance(cls):
        # cls 类名
        if cls.instance:
            return cls.instance
        else:
            obj = cls("pesen")
            cls.instance = obj
            return obj

obj1 = Foo.get_instance()
print(obj1)
obj2 = Foo.get_instance()
print(obj2)

 

posted on 2016-06-20 22:57  Pesen  阅读(476)  评论(0编辑  收藏  举报

导航