python类的构造使用以及例子+python的魔法方法+迭代器

学习的路径:戳一戳

本篇博客说明

最后的几个知识点,单纯看文档有点吃力,我再去康康视频,后续应该会有他们的详细补发博客,这个只是做个记录。

定义一个简单的类

基本语法:

class 函数名:
    函数体

对象名 = 函数名( )
对象名.(需要的数或者方法)

注意:

  • 由于下面这个代码,并没有对nameageheight进行修饰,由于python的值可以到处跑,所以说在下方改变name,也就是把name的值修改了,所以输出的就不是Bessie_Lee,而是Bessie

代码显示:

class hh:
    name = "Bessie_Lee"
    age = 18
    height = 161
    def major(self):
        print("I am a software engineering student")
    def time(self):
        print("I start to study at half past eight every morning!")

h = hh()
h.major()
h.time()
h.name = "Bessie"
print(h.name)

'''输出:
I am a software engineering student
I start to study at half past eight every morning!
Bessie
'''

使用私有方法(构造方法)__init__

  • 下面的类,就可以直接在创建对象名的时候传入对应参数
  • 注意:
  • 如果传入参数的时候,没有指定哪个传入哪个,就一定要按照类里面的参数顺序传入:
    • 对应例子:类里面:def __init__(self, age, name):,对应的调用h = hh(18, "Bessie_Lee")
  • 如果传入的参数指定哪个传入哪个,就不用管顺序
    • 对应例子:类里面:def __init__(self, age, name):,对应的调用h = hh(name = "Bessie_Lee", age = 18)【指定哪个是哪个的参数】
class hh:
    def __init__(self, age, name):
        self_age = age
        self_name = name
    def major(self):
        print("I am a software engineering student")
    def time(self):
        print("I start to study at half past eight every morning!")

h = hh(name = "Bessie_Lee", age = 18)
h.major()
h.time()
h.name = "Bessie"
print(h.name)

'''代码输出:
I am a software engineering student
I start to study at half past eight every morning!
Bessie
'''

pass语句+函数

  • pass - 啥作用都没有,就是可以给你留一个空格出来,保证代码不会报错
class MyList(list):
    pass

lis = MyList([12, 34, 45, 56])
lis.append(89)
lis.sort()
print(lis)
# [12, 34, 45, 56, 89]

调用父类的俩种方法

  • 父类名.__init__(self)
  • super().__init__()

对应代码:

import random
class Fish:
    def __init__(self):
        self.x = random.randint(0, 10)
        self.y = random.randint(0, 10)

    def move(self):
        self.x -= 1
        print("我的位置", self.x, self.y)


class Shark(Fish):  # 鲨鱼
    def __init__(self):
    #    Fish.__init__(self)
        super().__init__()
        self.hungry = True

    def eat(self):
        if self.hungry:
            print("吃货的梦想就是天天有得吃!")
            self.hungry = False
        else:
            print("太撑了,吃不下了!")
            self.hungry = True

a = Shark()
a.eat() #吃货的梦想就是天天有得吃!

同名属性和方法

class A:
    x = 10
    def x(self):
        print("same!")

p = A()
p.x() # same!
p.x = 199
print(p.x) # 199

绑定(我也不太会)

  • Python 对象的数据属性通常存储在名为.__ dict__的字典中,我们可以直接访问__dict__,或利用 Python 的内置函数vars()获取.__ dict__。

代码说明:

class CC:
    def setXY(self, x, y):
        self.x = x
        self.y = y

    def printXY(self):
        print(self.x, self.y)

dd = CC()
print(dd.__dict__) # {}
print(vars(dd)) # {}
print(CC.__dict__) # ①

dd.setXY(4, 5)
print(dd.__dict__) # {'x': 4, 'y': 5}
print(vars(CC)) # ①
print(CC.__dict__) # ①

# 称为:① :{'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000019FB236C4C0>, 'printXY': <function CC.printXY at 0x0000019FB236C550>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}

魔法方法

  • __new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行,将没有__init__被调用。

利用__new__实现单例模式

class Earth:
    __instance = None  # 定义一个类属性做判断

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance


a = Earth()
print(id(a))  # 2945214668704
b = Earth()
print(id(b))  # 2945214668704

实例化

  • __new__方法主要是当你继承一些不可变的 class 时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。
class CapStr(str):
    def __new__(cls, string):
        string = string.upper()
        return str.__new__(cls, string)


a = CapStr("i love lsgogroup")
print(a)  # I LOVE LSGOGROUP

加法减法(有点重要)

__add__(self, other)定义加法的行为:+
__sub__(self, other)定义减法的行为:-

代码:

class MyClass:

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

    # 两个对象的长相加,宽不变.返回一个新的类
    def __add__(self, others):
        return MyClass(self.height + others.height, self.weight + others.weight)

    # 两个对象的宽相减,长不变.返回一个新的类
    def __sub__(self, others):
        return MyClass(self.height - others.height, self.weight - others.weight)

    # 说一下自己的参数
    def intro(self):
        print("高为", self.height, " 重为", self.weight)


def main():
    a = MyClass(height=10, weight=5)
    a.intro()

    b = MyClass(height=20, weight=10)
    b.intro()

    c = b - a
    c.intro()

    d = a + b
    d.intro()


if __name__ == '__main__':
    main()

# 高为 10  重为 5
# 高为 20  重为 10
# 高为 10  重为 5
# 高为 30  重为 15

其他方法

  • __mul__(self, other)定义乘法的行为:*
  • __truediv__(self, other)定义真除法的行为:/
  • __floordiv__(self, other)定义整数除法的行为://
  • __mod__(self, other) 定义取模算法的行为:%
  • __divmod__(self, other)定义当被 divmod() 调用时的行为
    divmod(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)

反算术运算符(我不懂)

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

  • 注意 self 在后面

class Nint(int):
    def __radd__(self, other):
        return int.__sub__(other, self) # 注意 self 在后面


a = Nint(5)
b = Nint(3)
print(a + b)  # 8
print(1 + b)  # -2

这个知识点好抽象。。。。。我想看网课,这个文字看的我有点麻
在这里插入图片描述

class C:
    def __getattribute__(self, item):
        print('__getattribute__')
        return super().__getattribute__(item)

    def __getattr__(self, item):
        print('__getattr__')

    def __setattr__(self, key, value):
        print('__setattr__')
        super().__setattr__(key, value)

    def __delattr__(self, item):
        print('__delattr__')
        super().__delattr__(item)


c = C()
c.x
# __getattribute__
# __getattr__

c.x = 1
# __setattr__

del c.x
# __delattr__

描述符

  • __get__(self, instance, owner)用于访问属性,它返回属性的值。
  • __set__(self, instance, value)将在属性分配操作中调用不返回任何内容
  • __del__(self, instance)控制删除操作,不返回任何内容

格式:

class MyDecriptor:
    def __get__(self, instance, owner):
        print('__get__', self, instance, owner)

    def __set__(self, instance, value):
        print('__set__', self, instance, value)

    def __delete__(self, instance):
        print('__delete__', self, instance)


class Test:
    x = MyDecriptor()


t = Test()
t.x
# __get__ <__main__.MyDecriptor object at 0x000000CEAAEB6B00> <__main__.Test object at 0x000000CEABDC0898> <class '__main__.Test'>

t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x00000023687C6B00> <__main__.Test object at 0x00000023696B0940> x-man

del t.x
# __delete__ <__main__.MyDecriptor object at 0x000000EC9B160A90> <__main__.Test object at 0x000000EC9B160B38>

编写一个不可改变的自定义列表,要求记录列表中每个元素被访问的次数

class CountList:
    def __init__(self, *args):
        self.values = [x for x in args]
        self.count = {}.fromkeys(range(len(self.values)), 0)

    def __len__(self):
        return len(self.values)

    def __getitem__(self, item):
        self.count[item] += 1
        return self.values[item]


c1 = CountList(1, 3, 5, 7, 9)
c2 = CountList(2, 4, 6, 8, 10)
print(c1[1])  # 3
print(c2[2])  # 6
print(c1[1] + c2[1])  # 7

print(c1.count)
# {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}

print(c2.count)
# {0: 0, 1: 1, 2: 1, 3: 0, 4: 0}

迭代器

  • 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
  • 迭代器只能往前不会后退。
  • 字符串,列表或元组对象都可用于创建迭代器:
string = 'lsgogroup'
for c in iter(string):
    print(c, end = " ")
# l s g o g r o u p 
links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}
for each in iter(links):
    print(each, end=" ")
    print('%s -> %s' % (each, links[each]))
'''
B B -> 百度
A A -> 阿里
T T -> 腾讯
'''

生成器

def libs(n):
    a = 0
    b = 1
    while True:
        a, b = b, a + b
        if a > n:
            return
        yield a


for each in libs(100):
    print(each, end=' ')

# 1 1 2 3 5 8 13 21 34 55 89
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bessie_Lee_gogogo

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值