python面向对象

一:python模块

1、模块的定义

    模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py,我们可以将一个python文件,看做是一个模块。

        python的包:用来存放模块的文件夹,管理模块的。

        在项目包的目录中,只有包含一个叫做 __init__.py 的文件,才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

#package01包下的Dog.py
def eating(str):
    print('小狗正在吃{0}...'.format(str))
def play(str):
    print('小狗正在玩{0}...'.format(str))
def method():
    print('Dog类:',__name__)

2、导入模块

    模块可以被别的程序引入,以使用该模块中的函数等功能。(这也是使用python标准库的方法)。在当前python文件中,想使用其他模块(Python 源文件)的函数和变量,只需要在当前源文件里执行 import 语句.

语法1:

    import 模块的名称

    模块名.函数名

#导入系统模块
import sys   #导入sys模块
#打印出当前文件的路径
print('当前Python文件的路径为:\n\t', sys.path, '\n')
print('---------------------')
#导入自定义的模块  as指,取一个别名
import package01.Dog as dog
dog.eating('骨头')

运行结果:

当前Python文件的路径为:
   ['D:\\pythondemo\\demo\\package01', 'D:\\pythondemo\\demo', 'C:\\adminRun\\360\\pythonide\\PyCharm Community Edition 5.0.2\\helpers\\pycharm', 'C:\\conda\\python36.zip', 'C:\\conda\\DLLs', 'C:\\conda\\lib', 'C:\\conda', 'C:\\conda\\lib\\site-packages', 'C:\\conda\\lib\\site-packages\\win32', 'C:\\conda\\lib\\site-packages\\win32\\lib', 'C:\\conda\\lib\\site-packages\\Pythonwin'] 

---------------------
小狗正在吃骨头...

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。

语法2:

    from 模块名 import 函数名

    from 模块名 import *    #导入模块全部功能,不建议使用,一般不会用到模块的所有功能。

#导入一个函数
from package01.Dog import eating
eating('骨头')
print('--------------------------')
#导入多个函数
from package01.Dog import eating,play
eating('骨头')
play('飞盘')

运行结果:

小狗正在吃骨头...
--------------------------
小狗正在吃骨头...
小狗正在玩飞盘...

 3、模块的__name__属性

 在python中创建一个空的python文件时候,会默认写一些内容,这些内容继承object父类,每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,如果不是,则为这个模块的名称,表示被引入。
    __main__一般作为函数的入口,尤其在大型工程中,常常有if __name__ == "__main__":来表明整个工程开始运行的入口。
from package01.Dog import method
print('当前类:',__name__) #运行的当前类,值为:__main__
method()  #引用其他模块,值为:package01.Dog

#作为程序方法的入口
if __name__ =="__main__":
    print("hello...")

运行结果:

当前类:__main__
Dog类:package01.Dog
hello...

4、dir() :内置的函数 

    可以找到模块内定义的所有名称,以一个字符串列表的形式返回。

class_values = dir()
print(class_values)

运行结果:

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

二:面向对象

1、编程思想:看待事物,解决问题的一种角度

①、面向过程

    关注的焦点是过程(关注执行事物的动作,考虑的问题多,开发前后依赖性强)

    分工案例:打开冰箱、放入苹果[依赖太大,不打开冰箱,不能放入苹果]、关闭冰箱

②、面向对象:

    关注的焦点是对象(关注一个个对象,找到众多对象[创建对象]->使用对象[通过对象的功能]->维护对象之间的关系)

     分工案例:苹果、冰箱、人   [对象之间,没有太大关系]

面向对象,其实是对面向过程的封装(把过程封装到了对象的内部)

2、python面向对象编程

①、对象

    万物皆对象(真实存在于世界中的事物都是对象),对象会占用一定空间.

②、对象的特征:

    对象包括两个数据成员(类变量和实例变量)和方法。

    属性:自身组成的特征(形容词)  -> 变量

    功能:能够用来做什么(动词) -> 方法

③、类(先有对象后有类)

    先从对象中,观察(提取特征)分析功能和属性,将这些功能和属性定义为一种抽象的概念,叫做类(用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。)

④、类与对象的关系

    类是对象的抽象描述,对象是类的实例。

    人拥有意识中的常识,提到猫,大家就不会想到狗,是因为你的意识中已经认定为猫了,已经为这类事物分类啦!为什么大家意识中的猫,各不相同,因为猫是不存在的,只知道是一个什么事物。

    汽车图纸(类) ->根据图纸,创造的汽车实例为对象

⑤、类变量(类变量通常不作为实例变量使用)

    类变量在整个实例化的对象中是公用的。

    类变量定义在类中且在函数体之外。

⑥、实例变量

    定义在方法中的变量,只作用于当前实例的类

数据成员指类变量或者实例变量用于处理类及其实例对象的相关的数据。

⑦、类的方法(类中定义的函数)

    在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self, 且为第一个参数,self 代表的是类的实例,代表当前对象的地址,而非类,而 self.class 则指向类。self 不是 python 关键字,名字并不是规定死的,我们把他换成 abc,也可以使用 this ,但是最好还是按照约定是用 self。

⑧、构造方法

    很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法(构造方法)

    类定义了 __init__() 方法的话,类的实例化操作会自动调用 __init__() 方法。

    __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。

⑨、实例化:

    创建一个类的实例,也就是类的具体对象。

    类实例化后,可以通过实例名访问其属性,以及调用其方法

#轿车类
class Car:
    #类变量(类变量被所有的类对象共享)
    color = '白色'
    name = '特斯拉'
    speed = '360km/h'

    #构造方法 (初始化对象、创建对象时自动调用)
    def __init__(self):
        #实例变量(定义在方法中的变量,只作用于当前实例的类)
        self.other = '其他value'     
    #普通方法
    def run(self):
        age = 3 #局部变量(方法内使用)
        print('车跑起来了....颜色:{0},型号{1},时速:{2},其他:{3}'
              .format(self.color,self.name,self.speed,self.other))
              
#实例化对象,创建对象
c1 = Car()
c1.color = '红色'  #为对象的属性赋值
c1.name = '宝马'
print(c1.name) #获得对象的属性值
c1.run() #调用对象的方法
#类对象(类也是对象)
#类对象可以直接使用类变量
#类对象支持两种操作:1.实例化实例对象   2.引用属性obj.name(),不能引用方法
Car.color = '蓝色'
print(Car.color)

运行结果:

宝马
车跑起来了....颜色:红色,型号宝马,时速:360km/h,其他:其他value
蓝色

__init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。 

#轿车类
class Car:
    #类变量(类变量被所有的类对象共享)
    color = '白色'
    name = '特斯拉'
    speed = '360km/h'

    #构造方法(初始化对象、创建对象时自动调用)
    def __init__(self,other):
        self.other = other
    #方法
    def run(self):
        age = 3 #局部变量 (方法内使用)
        print('车跑起来了....颜色:{0},型号{1},时速:{2},其他:{3}'
              .format(self.color,self.name,self.speed,self.other))

#实例化对象,创建对象
c1 = Car('非常棒!')
c1.run()

运行结果:

车跑起来了....颜色:白色,型号特斯拉,时速:360km/h,其他:非常棒!

3、继承

    体现的是类与类之间的一种类似于父子的关系。

    Python 同样支持类的继承,即一个派生类(子类)继承基类(父类)的字段和方法。继承也允许把一个派生类(子类)的对象作为一个基类(父类)对象对待。Python同样有限的支持多继承形式,写法如:class DerivedClassName(Base1, Base2, Base3): ,需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。

    场合:继承的应用,应该符合...is...a...的关系,如:学生、工人...  是is   a 人...

    作用:子类继承父类,会拥有父类中所有的非私有属性和方法,更好的做到代码的复用。

①、继承案例一(学生student、工人worker,都继承人类person)

#父类 人类
class person:
    def eat(self):
        print('吃饭...')
    def speak(self):
        print('说话...')
 #子类 学生类
class student(person):
    def study(self):
        print('读书学习写作业...')
    # def eat(self):
    #     print('吃饭...')
    # def speak(self):
    #     print('说话...')
#子类 工人类
class worker(person):
    def work(self):
        print('搬砖')
    # def eat(self):
    #     print('吃饭...')
    # def speak(self):
    #     print('说话...')

s1 = student()
w1 = worker()
s1.study()
s1.eat()  #继承过来的方法
s1.speak() #继承过来的方法

运行结果:

读书学习写作业...
吃饭...
说话...

②、继承案例二(波斯猫persian_cat继承猫cat,猫cat继承动物animal)

#动物
class animal:
    def eat(self):
        print('吃东西...')

#
class cat(animal):
    def catch_mouse(self):
        print('抓老鼠...')

#波斯猫
class persian_cat(cat):
    def cute(self):
        print('卖萌...')

#波斯猫persian_cat继承猫cat,猫cat继承动物animal
#此时,子类波斯猫,拥有猫与动物类中声明的方法
pc1 = persian_cat()
pc1.eat()
pc1.catch_mouse()
pc1.cute()

运行结果:

吃东西...
抓老鼠...
卖萌...

③、python的多继承

#父类 
class A:
    def pr(self):
        print("A")
#父类 
class B:
    def pr(self):
        print("B")
#子类
class C(A,B):
    def pr(self):
        print("C")

c = C()
#python可以多继承,一个类可以继承多个父类,调用方法时,先从自己的类中找,自己的类没有,就到父类中找,
# 父类查找顺序,取决于继承时的抒写顺序(A,B)
c.pr()

"""
注意:这种继承方式会报错
class A:
class B(A):
class C(A,B):
"""

运行结果:

C

4、方法重写

    如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写,super() 函数是用于调用父类(超类)的一个方法。

#动物类
class animal:
    def eat(self):
        print('吃饭...')

#宠物狗类
class dog(animal):
    # 方法的重写。
    # 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    def eat(self):
        super().eat()
        print('吃骨头...')

dog1 = dog()
dog1.eat()

运行结果:

吃饭...
吃骨头...

子类继承父类,调用子类、父类共有的方法,最终是执行子类的方法

#父类 
class AA:

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

    def pr(self):
        print("AA")
        print(self.name)
#子类
class CC(AA):

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

    def pr(self):
        print("CC")
        print(self.name)

c = CC('哈哈')
c.pr()

运行结果:

CC
哈哈

5、私有属性与私有方法

    __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在 类内部的方法中使用时 self.__private_attrs

    __private_met两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methodshod:

class Demo:
    def __init__(self,age):
        #属性私有
        self.__age = age

    def pr(self):
        print('你的年龄是:',self.__age)
        #在类的内部调用私有方法
        self.__abc()

    #封装(解决,类的外部不能使用私有属性的问题)
    def chage_age(self,age):
        if 0<age<120:
            self.__age=age
        else:
            print('年龄不合法')

    #方法私有
    def __abc(self):
        print("私有方法")


demo = Demo(23)
demo.__age = 30  #不能改变
demo.pr()
demo.chage_age(30)
demo.pr()
#demo.__abc() #调用时报错

运行结果:

你的年龄是:23
私有方法
你的年龄是:30
私有方法

6、类的专有方法:

class Demo(object):
    pass

#创建对象
demo= Demo()
#引用类的专有方法
demo.#打点,会提示众多类的专有方法

__init__ : 构造函数,在生成对象时调用

    __str__:获取属性信息时调用

    __del__ : 析构函数,释放对象时使用

    __repr__ : 打印,转换

    __setitem__ : 按照索引赋值

    __getitem__: 按照索引获取值

    __len__: 获得长度

    __cmp__: 比较运算

    __call__: 函数调用

    __add__: 加运算

    __sub__: 减运算

    __mul__: 乘运算

    __div__: 除运算

    __mod__: 求余运算

    __pow__: 乘方

# __str__()的应用
class studentstr:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

class studentstr2(object):

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

    #运算符的重载(重写系统提供的专有方法)
    def __str__(self):
        return '姓名:{0}\t年龄:{1}\t性别:{2}'.format(self.name,self.age,self.sex)

ss1 = studentstr('小明',18,'')
print(ss1)  #打印的是内存地址
ss2 = studentstr2('小明',18,'')
print(ss2)  #打印的是__str__方法指定的值

运行结果:

<demoTest04.studentstr object at 0x0000012DB1489518>
姓名:小明  年龄:18  性别:男

 

posted @ 2020-02-28 15:43  后山人  阅读(240)  评论(0编辑  收藏  举报