栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python类和对象

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python类和对象

1.封装

把“乱七八糟”的数据扔进列表里 边,这是一种封装,是数据层面的封装;

把常用的代码段打包成一个函数,这也是一种封装,是语句层面的封装

对象,也是一种封装的思想,不过这种思想显然要更先进一些:面向对象的灵感来源是模拟真实的世界,把数据和代码都封装在了一起。

对象=属性+方法;一个对象的特征称为“属性”,一个对象 的行为称为“方法”。

class Turtle:
    # Python中的类名约定以大写字母开头
    # 特征的描述我们称为属性,在代码层面来看其实就是变量
    color = 'green'
    weight = 10
    legs = 4
    shell = True
    mouth = '大嘴'

    # 方法实际就是函数,通过调用这些函数来完成某些工作
    def climb(self):
        print("我正在很努力的向前爬......")

    def run(self):
        print("我正在飞快的向前跑......")

    def bite(self):
        print("咬死你咬死你!!")

    def eat(self):
        print("有得吃,真满足^_^")

    def sleep(self):
        print("困了,睡了,晚安,Zzzz")

实例化对象时类名后面跟着小括号,这与调用函数是一样的,所以在Python中, 类名约定用大写字母开头,函数用小写字母开头,这样更容易区分。另外赋值操作并不是必需的,但如果没有把创建好的实例对象赋值给一个变量,那这个对象就没办法使用,因为没有任何引用指向这个实例,最 终会被Python的垃圾收集机制自动回收。

对象的方法都会有一个self参数,Python的self其实就相当于C++的this 指针。由同一个类可以生成无数对象,当一个对象的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,那么Python就知道需要操作哪个对象的方法了。例子如下:

class Ball:
    def setName(self, name):
        self.name = name
    def kick(self):
        print("我叫%s,奥~谁踢我?!" % self.name)
        
a = Ball()
a.setName("飞火流星")
b = Ball()
b.setName("团队之星")
c = Ball()
c.setName("土豆")

a.kick()
b.kick()
c.kick()

#我叫飞火流星,奥~谁踢我?!
#我叫团队之星,奥~谁踢我?!
#我叫土豆,奥~谁踢我?!

2.魔法方法

_ _init_ _()方法称为构造方法,_ _init_ _()方法的魔力体现在 只要实例化一个对象,这个方法就会在对象被创建时自动调用(在 C++里也可以看到类似的东西,叫“构造函数”)

3.公有和私有

一般面向对象的编程语言都会区分公有和私有的数据类型,像 C++和Java,它们使用public和private关键字,用于声明数据是公有的还 是私有的,但在Python中并没有用类似的关键字来修饰。python中默认对象的属性和方法都是公开的,可以直接通过点操作符(.)进行访问。Python内部采用了一种叫Name Mangling(名字改编)的技术,在Python中定义私有变量只需要在变量
名或函数名前加上“_ _”两个下画线,那么这个函数或变量就会成为私有的。Python目前的私有机制其实是伪私有,Python的类是没有权限控制的,所有变量都是可以被外部调用的。实际上在外部使用“_类名_ _变量名”即可访问两个下画线开头的私有变量。

 4.继承

被继承的类称为基类、父类或超类;继承者称为子类,一个子类可 以继承它的父类的任何属性和方法。子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。

5.

1)调用未绑定的父类方法。2)  使用super函数。

这里说的未绑定是指并不需要绑定父类的实 例对象,使用子类的实例对象代替即可

super函数能够自动找到基类的方法,而且还传入了self参数。super函数的“超级”之处在于:不需要明确给出任何基类的名字,它 会自动找出所有基类以及对应的方法。由于不用给出基类的名字,这就 意味着如果需要改变类继承关系,只要改变class语句里的父类即可,而 不必在大量代码中去修改所有被继承的方法。

6.多重继承

 注意使用super().__init__()规避钻石继承(菱形继承)问题

7.组合

 直接把需要的类放进去实例化

# p11_3.py
class Turtle:
    def __init__(self, x):
        self.num = x


class Fish:
    def __init__(self, x):
        self.num = x


class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)

    def print_num(self):
        print("水池里总共有乌龟 %d 只,小鱼 %d 条!" % (self.turtle.num, self.fish.num))


p = Pool(1, 10)
p.print_num()

#水池里总共有乌龟 1 只,小鱼 10 条!

Python的特性其实还支持另外一种很流行的编程模式:Mixin,

8.类、类对象和实例对象

类中定义的属性是静态变量,也就是相当于C语言 中加上static关键字声明的变量,类的属性是与类对象进行绑定,并不会依赖任何它的实例对象。注意可以使用 实例对象.__dict__ 和类名.__dict__分别查看属于他们的字段

class C:
    x = 0
    def __init__(self, x=0):
        self.x=x
c=C(5)
c.x #5
C.x #0
#hasattr(C, 'x') #True

如果属性的名字与方法名相同,属性会覆盖方法

为了避免名字上的冲突,编写代码时应该遵守一些约定俗成的规 矩: • 类的定义要“少吃多餐”,不要试图在一个类里边定义出所有能 想到的特性和方法,应该利用继承和组合机制来进行扩展。 • 用不同的词性命名,如属性名用名词、方法名用动词,并使用 骆驼命名法。骆驼式命名法(CamelCase)又称驼峰命名法,是 电脑程式编写时的一套命名规则(惯例)。正如它的名称 CamelCase所表示的那样,是指混合使用大小写字母来构成变量 和函数的名字,程序员为了自己的代码能更容易在同行之间交 流,所以多采取统一的可读性比较好的命名方式。

9.与类和对象相关的一些BIF(内置函数)

1)issubclass(class, classinfo)

2)isinstance(object, classinfo)

Python提供了以下几个BIF用于访问对象的属性。

3)hasattr(object, name)

4)getattr(object, name[, default])

5)setattr(object, name, value)

6)delattr(object, name)

7)property(fget=None, fset=None, fdel=None, doc=None):作用是通过属性来设置属性。

10.魔法方法

构造和析构

1)_ _init_ _(self[, ...])

_ _init_ _()方法的返回值一定是None,只有在需要进行初始化的时候才重写_ _init_ _()方法

2)_ _new_ _(cls[, ...])

事实上,_ _new_ _()才是在一个对象实例化的时候调用的第一个方 法。它与其他魔法方法不同,它的第一个参数不是self而是这个类 (cls),而其他的参数会直接传递给_ _init_ _()方法。继承一个 不可变的类型的时候需要重写

3)_ _del_ _(self):当垃圾回收机制回收这个对象的时候调用;即没有了对这一实例的引用变量;

算术运算

Python 2.2以后,对类和类型进行了统一,做法就是将int()、 float()、str()、list()、tuple()这些BIF转换为工厂函数。所谓的工厂函数,其实就是一个类对象。当调用它们的时候,事实上就是创建一个相应的实例对象。Python中无处不对象,当在求a + b等于多少的时候,事实 上Python就是将两个对象进行相加操作

常见的算术运算

 反运算

 有无大佬在评论区解释下这个是什么意思?

 一元操作符 

如__neg__();__pos__(); __abs__(); __invert__();

其他

_ _str_ _()和_ _repr_ _()魔法方法。

计时器综合练习

# p12_2.py
import time as t

class MyTimer:
    def __init__(self):
        self.prompt = "未开始计时!"
        self.lasted = []
        self.start = 0
        self.stop = 0

    def __init__(self):
        self.unit = ['年', '月', '天', '小时', '分钟', '秒']
        self.prompt = "未开始计时!"
        self.lasted = []
        self.begin = 0
        self.end = 0

    # 开始计时
    def start(self):
        self.begin = t.localtime()
        self.prompt = "提示:请先调用 stop() 开始计时!"
        print("计时开始...")

    # 停止计时
    def stop(self):
        if not self.begin:
            print("提示:请先调用 start() 开始计时!")
        else:
            self.end = t.localtime()
            self._calc()
            print("计时结束!")

    # 计算运行时间
    def _calc(self):
        self.lasted = []
        self.prompt = "总共运行了"
        for index in range(6):
            self.lasted.append(self.end[index] - self.begin[index])
            if self.lasted[index]:
                self.prompt += (str(self.lasted[index]) + self.unit[index])
        # 为下一轮计算初始化变量
        self.begin = 0
        self.end = 0

    # 重写add方法
    def __add__(self, other):
        prompt = "总共运行了"
        result = []
        for index in range(6):
            result.append(self.lasted[index] + other.lasted[index])
            if result[index]:
                prompt += (str(result[index]) + self.unit[index])
        return prompt

    def __str__(self):
        return self.prompt
    
    __repr__ = __str__
# >>> t1 = MyTimer()
# >>> t1
# 未开始计时!
# >>> t1.stop()
# 提示:请先调用 start() 开始计时!
# >>> t1.start()
# 计时开始...
# >>> t1
# 提示:请先调用 stop() 结束计时!
# >>> t1.stop()
# 计时结束!
# >>> t1
# 总共运行了8秒
# >>> t2 = MyTimer()
# >>> t2.start()
# 计时开始...
# >>> t2.stop()
# 计时结束!
# >>> t2
# 总共运行了4秒
# >>> t1 + t2
# '总共运行了12秒'

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1015740.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号