第七次学习打卡----类与对象,魔法方法

类与对象

1. 对象 = 属性 + 方法

1. 封装:信息隐蔽技术

我们可以使用关键字 class 定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。


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('困了,睡了,晚安,zzz')
tt = Turtle()
print(tt)
# <__main__.Turtle object at 0x0000007C32D67F98>
print(type(tt))
# <class '__main__.Turtle'>

print(tt.__class__)
# <class '__main__.Turtle'>
print(tt.__class__.__name__)
# Turtle
tt.climb()
# 我正在很努力的向前爬...
tt.run()
# 我正在飞快的向前跑...
tt.bite()
# 咬死你咬死你!!
# Python类也是对象。它们是type的实例
print(type(Turtle))
# <class 'type'>

**.继承:**子类自动共享父类之间数据和方法的机


class MyList(list):
 pass
lst = MyList([1, 5, 2, 7, 8])
lst.append(9)
lst.sort()
print(lst)
# [1, 2, 5, 7, 8, 9]

多态:不同对象对同一方法响应不同的行动


 def run(self):
 raise AttributeError('子类必须实现这个方法')
class People(Animal):
 def run(self):
 print('人正在走')
 
class Pig(Animal):
 def run(self):
 print('pig is walking')
class Dog(Animal):
 def run(self):
 print('dog is running')
def func(animal):
 animal.run()
func(Pig())
# pig is walking

2. self 是什么?

Python 的 self 相当于 C++ 的 this 指针。


class Test:
 def prt(self):
 print(self)
 print(self.__class__)
t = Test()
t.prt()
# <__main__.Test object at 0x000000BC5A351208>
# <class '__main__.Test'>

class Ball:

def setName(self, name):
 self.name = name
 def kick(self):
 print("我叫%s,该死的,谁踢我..." % self.name)
a = Ball()
a.setName("球A")
b = Ball()
b.setName("球B")
c = Ball()
c.setName("球C")
a.kick()
# 我叫球A,该死的,谁踢我...
b.kick()
# 我叫球B,该死的,谁踢我

3. Python 的魔法方法


class Ball:
 def __init__(self, name):
 self.name = name
 def kick(self):
 print("我叫%s,该死的,谁踢我..." % self.name)
a = Ball("球A")
b = Ball("球B")
c = Ball("球C")

a.kick()
# 我叫球A,该死的,谁踢我...
b.kick()
# 我叫球B,该死的,谁踢我...

4. 公有和私有

类的私有属性实例


class JustCounter:
 __secretCount = 0 # 私有变量
 publicCount = 0 # 公开变量
 def count(self):
 self.__secretCount += 1
 self.publicCount += 1
 print(self.__secretCount)
counter = JustCounter()
counter.count() # 1
counter.count() # 2
print(counter.publicCount) # 2
print(counter._JustCounter__secretCount) # 2 Python的私有为伪私有
print(counter.__secretCount) 
# AttributeError: 'JustCounter' object has no attribute '__secretCount'

类的私有方法实例

5. 继承

class DerivedClassName(BaseClassName):
 <statement-1>
 .
 .
 .
 <statement-N>

如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。


class people:
 # 定义基本属性
 name = ''
 age = 0
 # 定义私有属性,私有属性在类外部无法直接进行访问
 __weight = 0
 # 定义构造方法
 def __init__(self, n, a, w):
 self.name = n
 self.age = a
 self.__weight = w
 def speak(self):
 print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
 grade = ''
 def __init__(self, n, a, w, g):
 # 调用父类的构函
 people.__init__(self, n, a, w)
 self.grade = g
 # 覆写父类的方法
 def speak(self):
 print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
s = student('小马的程序人生', 10, 60, 3)
s.speak()
# 小马的程序人生 说: 我 10 岁了,我在读 3 年级
注意:如果上面的程序去掉: people.__init__(self, n, a, w) ,则输
出: 说:0 岁了,我在读 3 年级 ,因为子类的构造方法把父类的构造方法覆盖了。
【例子】
class Fish:
 def __init__(self):
 self.x = r.randint(0, 10)
 self.y = r.randint(0, 10)
 def move(self):
 self.x -= 1
 print("我的位置", self.x, self.y)
class GoldFish(Fish): # 金鱼
 pass
class Carp(Fish): # 鲤鱼
 pass
class Salmon(Fish): # 三文鱼
 pass
class Shark(Fish): # 鲨鱼
 def __init__(self):
 self.hungry = True
 def eat(self):
 if self.hungry:
 print("吃货的梦想就是天天有得吃!")
 self.hungry = False
 else:
 print("太撑了,吃不下了!")
 self.hungry = True
g = GoldFish()
g.move() # 我的位置 9 4
s = Shark()
s.eat() # 吃货的梦想就是天天有得吃!
s.move() 
# AttributeError: 'Shark' object has no attribute 'x

使用super函数 super().init()

类属性和实例属性区别

  1. 类属性:类外面,可以通过 实例对象.类属性 和 类名.类属性 进行调用。类里面,通过 self.类属性
    和 类名.类属性 进行调用。
  2. 实例属性 :类外面,可以通过 实例对象.实例属性 调用。类里面,通过 self.实例属性 调用。
  3. 实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。
  4. 类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。

习题
4.

15 魔法方法

魔法方法总是被双下划线包围,例如 init
魔法方法是面向对象的 Python 的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的 Python 的强大。
魔法方法的“魔力”体现在它们总能够在适当的时候被自动调用。
魔法方法的第一个参数应为 cls (类方法) 或者 self (实例方法)。
1. cls :代表一个类的名称
2. self :代表一个实例对象的名称

1. 基本的魔法方法

init(self[, …])

  1. 构造器,当一个实例被创建的时候调用的初始化方法

new(cls[, …])

  1. new 是在一个对象实例化的时候所调用的第一个方法,在调用 init 初始化前,先调用 new
  2. new 至少要有一个参数 cls ,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的
    参数直接传递给 init
  3. new 对当前类进行了实例化,并将实例返回,传给 init 的 self 。但是,执行了 new ,并不
    一定会进入 init ,只有 new 返回了,当前类 cls 的实例,当前类的 init 才会进入。

2. 算术运算符

  1. add(self, other) 定义加法的行为: +

  2. sub(self, other) 定义减法的行为: -

  3. mul(self, other) 定义乘法的行为: *

  4. truediv(self, other) 定义真除法的行为: /

  5. floordiv(self, other) 定义整数除法的行为: //

  6. mod(self, other) 定义取模算法的行为: %

  7. divmod(self, other) 定义当被 divmod() 调用时的行为

  8. divmod(a, b) 把除数和余数运算结果结合起来,返回一个包含商和余数的元组 (a // b, a % b) 。

  9. pow(self, other[, module]) 定义当被 power() 调用或 ** 运算时的行为

  10. lshift(self, other) 定义按位左移位的行为: <<

  11. rshift(self, other) 定义按位右移位的行为: >>

  12. and(self, other) 定义按位与操作的行为: &

  13. xor(self, other) 定义按位异或操作的行为: ^

  14. or(self, other) 定义按位或操作的行为: |

3. 反算术运算符

反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。当文件左操作不支持
相应的操作时被调用。

  1. radd(self, other) 定义加法的行为: +
  2. rsub(self, other) 定义减法的行为: -
  3. rmul(self, other) 定义乘法的行为: *
  4. rtruediv(self, other) 定义真除法的行为: /
  5. rfloordiv(self, other) 定义整数除法的行为: //
  6. rmod(self, other) 定义取模算法的行为: %
  7. rdivmod(self, other) 定义当被 divmod() 调用时的行为
  8. rpow(self, other[, module]) 定义当被 power() 调用或 ** 运算时的行为
  9. rlshift(self, other) 定义按位左移位的行为: <<
  10. rrshift(self, other) 定义按位右移位的行为: >>
  11. rand(self, other) 定义按位与操作的行为: &
  12. rxor(self, other) 定义按位异或操作的行为: ^
  13. ror(self, other) 定义按位或操作
    行为: |

a + b
这里加数是 a ,被加数是 b ,因此是 a 主动,反运算就是如果 a 对象的 add() 方法没有实现或者不支持相应
的操作,那么 Python 就会调用 b 的 radd() 方法。

练习;
1.、利用python做一个简单的定时器类
要求:

  1. 定制一个计时器的类。
  2. start 和 stop 方法代表启动计时和停止计时。
  3. 假设计时器对象 t1 , print(t1) 和直接调用 t1 均显示结果。
  4. 当计时器未启动或已经停止计时时,调用 stop 方法会给予温馨的提示。
  5. 两个计时器对象可以进行相加: t1+t2 。
  6. 只能使用提供的有限资源完成。
import time


class Mytime(object):
    def __init__(self):
        self.__info = '未开始计时!'
        self.__begin = None
        self.__end = None
        self.__jg = 0

    def __str__(self):
        return self.__info

    def __repr__(self):
        return self.__info

    def start(self):
        print('计时开始...')
        self.__begin = time.localtime()

    def stop(self):
        if not self.__begin:
            print('提示:请先调用start()开始计时!')
            return
        self.__end = time.localtime()
        self.__jg = time.mktime(self.__end) - time.mktime(self.__begin)
        self.__info = '共运行了%d秒' % self.__jg
        print('计时结束!')
        return self.__jg

    def __add__(self, other):
        return '共运行了%d秒' % (other.__jg + self.__jg)


t1 = Mytime()
print(t1)
# 未开始计时!
t1.stop()
# 提示:请先调用start()开始计时!
t1.start()
# 计时开始...
time.sleep(5)
t1.stop()
# 计时结束!
print(t1)
# 共运行了5秒
t2 = Mytime()
t2.start()
# 计时开始...
time.sleep(7)
t2.stop()
# 计时结束!
print(t2)
# 共运行了7秒
print(t1 + t2)
# 共运行了12秒

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值