首页 > 编程语言 > 详细

Python笔记(二)

时间:2019-06-19 10:57:32      阅读:205      评论:0      收藏:0      [点我收藏+]

一、面向对象

1、类与对象

类名要满足大驼峰命名法,每一个单词首字母都大写

(使用dir内置函数,可以查看对象内所有的属性和方法)

__方法名__ 格式的方法是 Python 提供的 内置方法 / 属性

序号方法名类型作用
01 __new__ 方法 创建对象时,会被 自动 调用
02 __init__ 方法 对象被初始化时,会被 自动 调用
03 __del__ 方法 对象被从内存中销毁前,会被 自动 调用
04 __str__ 方法 返回对象的描述信息print 函数输出使用

类中的方法第一个参数必须是self

class Cat:

    def eat(self):
        print("小猫爱吃鱼")

    def drink(self):
        print("小猫要喝水")


tom = Cat()
tom.eat()
tom.drink()

在Python中想给对象增加属性,只需要在 类的外部的代码 中直接通过 . 设置一个属性即可,这种方式虽然简单,但是不推荐使用;

class Cat:

    def eat(self):
        print("小猫%s爱吃鱼" % self.name)

    def drink(self):
        print("小猫%s要喝水" % self.name)


tom = Cat()
tom.name = "汤姆"
tom.eat()
tom.drink()

 

2、初始化方法

当使用类名()创建对象时,会自动执行:为对象在内存中分配空间、为对象的属性设置初始值;

__init__方法是专门用来定义一个类具有哪些属性的方法,是对象的内置方法;

class Cat:
    def __init__(self):
        print("初始化方法")
        self.name = ""

    def eat(self):
        print("小猫%s爱吃鱼" % self.name)

    def drink(self):
        print("小猫%s要喝水" % self.name)


tom = Cat()
tom.eat()
tom.drink()
class Cat:
    def __init__(self, name):
        print("初始化方法")
        self.name = name

    def eat(self):
        print("小猫%s爱吃鱼" % self.name)


tom = Cat("Tom")
tom.eat()

 

3、内置方法

当一个对象从内存中被销毁前,会自动调用__del__方法,对象的生命周期结束

当使用print打印对象变量时,如果希望打印自定义的内容,就可以利用__str__这个内置方法,__str__必须要返回一个字符串

class Cat:

    def __init__(self, name):
        self.name = name
        print("%s来了" % self.name)

    def __del__(self):
        print("%s走了" % self.name)

    def __str__(self):
        return "我是一只小猫,我叫%s" % self.name


tom = Cat("tom")
print(tom)

 

4、封装案例

class Person:

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

    def run(self):
        self.weight -= 0.5

    def eat(self):
        self.weight += 1

    def __str__(self):
        return "我叫%s,我的体重是%.1f" % (self.name, self.weight)


xiaomei = Person("小美", 90.0)
xiaomei.run()
xiaomei.eat()
print(xiaomei)
class HouseItem:

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

    def __str__(self):
        return "[%s]占地%.2f" % (self.name, self.area)


class House:

    def __init__(self, house_type, area):
        self.house_type = house_type
        self.area = area
        self.free_area = area
        self.item_list = []

    def __str__(self):
        return ("户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s" %
                (self.house_type, self.area, self.free_area, self.item_list))

    def add_item(self, item):
        if item.area > self.free_area:
            print("%s面积太大,无法添加" % item.name)
            return
        self.item_list.append(item.name)
        self.free_area -= item.area


bed = HouseItem("席梦思", 10)
print(bed)
chest = HouseItem("衣柜", 5)
print(chest)
table = HouseItem("餐桌", 5)
print(table)

my_home = House("两室一厅", 100)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
class Gun:

    def __init__(self, type):
        self.type = type
        self.bullet_count = 0

    def add_bullet(self, count):
        self.bullet_count += count

    def shoot(self):
        if self.bullet_count <= 0:
            print("没有子弹了")
            return
        self.bullet_count -= 3
        print("[%s]突突突...[%d]" % (self.type, self.bullet_count))


class Soldier:

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

    def fire(self):
        # 使用身份运算符is,用于比较对象的内存地址是否一致
        if self.gun is None:
            print("%s还没有枪" % self.name)
            return
        print("冲啊...[%s]" % self.name)
        self.gun.add_bullet(50)
        self.gun.shoot()


AK47 = Gun("AK47")
# AK47.add_bullet(50)
# AK47.shoot()

xusanduo = Soldier("许三多")
xusanduo.gun = AK47
xusanduo.fire()
运算符描述实例
is is 是判断两个标识符是不是引用同一个对象 x is y,类似 id(x) == id(y)
is not is not 是判断两个标识符是不是引用不同对象 x is not y,类似 id(a) != id(b)

 

5、私有属性和方法

 在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

class Woman:

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

    def secret(self):
        print("%s的年龄是%d" % (self.name, self.__age))


xiaoyuan = Woman("小圆")
xiaoyuan.secret()

在Python中并没有真正意义的私有(伪私有属性/方法),Python解释器会对私有属性和方法名做特殊处理:_类名__属性名

class Woman:

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

    def __secret(self):
        print("%s的年龄是%d" % (self.name, self.__age))


xiaoyuan = Woman("小圆")
print(xiaoyuan._Woman__age)
xiaoyuan._Woman__secret()

 

6、单继承

面向对象三大特性:

封装:根据职责将属性和方法封装到一个抽象的类中

继承:实现代码的重用,相同的代码不需要重复的编写

多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度

子类-父类-继承

派生类-基类-派生

class Animal:
    def eat(self):
        print("")

    def drink(self):
        print("")

    def run(self):
        print("")


class Dog(Animal):
    def bark(self):
        print("")


class XiaoTianQuan(Dog):
    def fly(self):
        print("")


wangcai = XiaoTianQuan()
wangcai.eat()
wangcai.run()
wangcai.bark()
wangcai.fly()

 

7、方法的重写

class Animal:
    def eat(self):
        print("")

    def run(self):
        print("")


class Dog(Animal):
    def bark(self):
        print("汪汪汪")


class XiaoTianQuan(Dog):
    def fly(self):
        print("")

    def bark(self):
        super().bark()
        print("哈哈哈")


wangcai = XiaoTianQuan()
wangcai.eat()
wangcai.bark()
wangcai.fly()

super()就是使用super类创建出来的对象

在Python2时,如果需要调用父类的方法,还可以使用以下方式:父类名.方法(self)(不推荐使用) 

 

8、间接访问父类私有属性和方法

通过父类公有方法间接访问父类的私有属性和私有方法

class A:
    def __init__(self, num1):
        self.num1 = num1
        self.__num2 = 2

    def __test(self):
        print("私有方法")

    def test(self):
        print(self.__num2)
        self.__test()


class B(A):
    pass


b = B(1)
b.test()

 

9、多继承

class A:
    def test(self):
        print("test方法")


class B:
    def demo(self):
        print("demo方法")


class C(A, B):
    pass


c = C()
c.test()
c.demo()

如果父类之间存在同名的属性或者方法,应该尽量避免使用多继承。

同名方法的调用,是根据Python中的MRO(method resolution order)方法搜索顺序,来决定的;

Python提供的__mro__可以查看方法搜索顺序:

print(C.__mro__)

输出:  (<class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘__main__.B‘>, <class ‘object‘>)

  • 在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
  • 如果在当前类中 找到方法,就直接执行,不再搜索
  • 如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
  • 如果找到最后一个类,还没有找到方法,程序报错

 

10、新式类与经典类

新式类:以object为基类,推荐使用,Python3中没有指定父类,会默认以object为基类,Python3中的类都是新式类

旧式类:不以object为基类,不推荐使用

新式类和旧式类在多继承时会影响到方法的搜索顺序

为了保证代码能在Python2/3运行,编写代码时,如果没有父类,建议统一继承自object

 

11、多态

不同的子类对象调用相同的父类方法,产生不同的执行结果

以继承和重写父类方法为前提

class Dog(object):
    def __init__(self, name):
        self.name = name

    def game(self):
        print("%s蹦蹦跳跳" % self.name)


class XiaoTianDog(Dog):
    def game(self):
        print("%s飞天" % self.name)


class Person(object):
    def __init__(self, name):
        self.name = name

    def game_with_dog(self, dog):
        print("%s与%s快乐的玩耍" % (self.name, dog.name))
        dog.game()


xtq = XiaoTianDog("哮天犬")
wc = Dog("旺财")
xm = Person("小明")

xm.game_with_dog(xtq)
xm.game_with_dog(wc)

传入不同的狗对象实参,就会产生不同的执行效果

 

12、类属性和类方法

每一个对象 都有自己 独立的内存空间,保存各自不同的属性

多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用 传递到方法内部

类是一个特殊的对象:类对象在内存中只有一份,在程序运行时,类同样会被加载到内存

类对象拥有自己的属性和方法,直接通过 类名. 的方式访问

 

Python笔记(二)

原文:https://www.cnblogs.com/ysysyzz/p/10923453.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!