python入门------魔法方法

简介: python入门------魔法方法

魔法方法总是被双下划线包围,例如__init__


魔法方法是面向对象的python的一切


魔法方法总能够在适当的时候被自动调用


_init_(self[, …])


问题:在写类定义的时候有些写__init__方法,有些却没有,为什么?


class Rectangle:     #矩形
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def getPeri(self):
        return (self.x + self.y) * 2
    def getArea(self):
        return self.x * self.y
rect = Rectangle(3, 4)
print(rect.getPeri())    #周长
print(rect.getArea())    #面积


14
12


_new_(cls[, …])


upper()


class CapStr(str):
    def __new__(cls, string):
        string = string.upper()
        return str.__new__(cls, string)
a = CapStr('Hu zhuzhu')
print(a)


HU ZHUZHU


_del_(self)


错误表示: del x = x._del_()


class C:
    def __init__(self):
        print('我是__init__方法,我被调用了...')
    def __del__(self):
        print('我是__del__方法,我被调用了...')
c1 = C()
c2 = c1
c3 = c2
del c3
del c1



print(type(len))
print(type(dir))
print(type(int))
print(type(list))
class C:
    pass
print(type(C))
print(type(int('123')))
print(type('123'))


<class 'builtin_function_or_method'>
<class 'builtin_function_or_method'>
<class 'type'>
<class 'type'>
<class 'type'>
<class 'int'>
<class 'str'>


class New_int(int):
    def __add__(self, other):
        return int.__sub__(self, other)
    def __sub__(self, other):
        return int.__add__(self, other)
a = New_int(3)
b = New_int(5)
print(a+b)    #int(a)-int(b)
print(a-b)


-2
8


class Try_int(int):
    def __add__(self, other):
        return int(self) + int(other)
    def __sub__(self, other):
        return int(self) - int(other)
a = Try_int(3)
b = Try_int(5)
print(a+b)
print(a-b)


8
-2



class int(int):
    def __add__(self, other):
        return int.__sub__(self, other)    #返回减法
a = int('5')
b = int(3)
print(a+b)


2


class Nint(int):
    def __radd__(self, other):
        return int.__sub__(self, other)
a = Nint('5')
print(a)
b = Nint(3)
print(a+b)
print(1+b)


5
8
2


class Nint(int):
    def __radd__(self, other):
        return int.__sub__(other, self)
a = Nint('5')
print(3-a)


-2


定时器




class A():
    def __str__(self):
        return '胡猪猪'
a = A()
print(a)
class B():
    def __repr__(self):
        return '胡大猪'
b = B()
print(b)


胡猪猪
胡大猪



import time as t    #调用import,   t  = import
class MyTimer():
    def __init__(self):
        self.unit = ['年', '月', '天', '小时', '分钟', '秒']
        self.prompt = '未开始计时!'
        self.lasted = []
        self.begin = 0
        self.end = 0
    def __str__(self):
       return self.prompt     #返回未开始计时
    __repr__ = __str__
    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 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):    #前六个,0-5
            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
        print(self.prompt)



描述符


就是将某种特殊类型的类的实例指派给另一个类的属性。


_get_(self, instance, owner)


用于访问属性,它返回属性的值


_set_(self, instance, value)


将在属性分配器操作中调用,不返回任何内容


_delete_(self, instance)


控制删除操作,不返回任何内容



class MyDecriptor:
    def __get__(self, instance, owner):     #用于访问属性,它返回属性的值
        print('getting...', self, instance, owner)
    def __set__(self, instance, value):     #将在属性分配器操作中调用,不返回任何内容
        print('setting...', self, instance, value) 
    def __delete__(self, instance):        #控制删除操作,不返回任何内容
        print('deleting...', self, instance)   
class Test:
    x = MyDecriptor()
test = Test()
test.x
print(test)
print(Test)
test.x = 'X.man'


getting... <__main__.MyDecriptor object at 0x0000014D64D845C8> <__main__.Test object at 0x0000014D64D846C8> <class '__main__.Test'>
<__main__.Test object at 0x0000014D64D846C8>   #test
<class '__main__.Test'>                        #Test
setting... <__main__.MyDecriptor object at 0x0000014D64D845C8> <__main__.Test object at 0x0000014D64D846C8> X.man


class MyProperty:
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    def __get__(self, instance, owner):    #用于访问属性,它返回属性的值
        return self.fget(instance)
    def __set__(self, instance, value):    #将在属性分配器操作中调用,不返回任何内容
        self.fset(instance, value)
    def __delete__(self, instance):        #控制删除操作,不返回任何内容
        self.fdel(instance)
class C:
    def __init__(self):
        self._x = None            #private
    def getX(self):
        return self._x
    def setX(self, value):
        self._x = value
    def delX(self):
        del self._x
    x = MyProperty(getX, setX, delX)
c = C()
c.x = 'X.man'    #赋值
print(c.x)
print(c._x)


X.man
X.man


练习1:摄氏度华氏度转换


1、先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性


2、要求两个属性会自动进行转换,给摄氏度输出华氏度,给华氏度输出摄氏度


class Celsius:
    def __init__(self, value = 26.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)
class Fahrenheit:
    def __get__(self, instance, owner):
        return instance.cel * 1.8 +32
    def __set__(self, instance, value):
        instance.cel = (float(value) - 32)/1.8
class Temperature:
    cel = Celsius()
    fah = Fahrenheit()
temp = Temperature()
temp.cel = 30
print(temp.fah)
temp.fah = 86
print(temp.cel)


86.0
30.0


协议


协议(Protocols)与其他编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在python中的协议就显得不那么正式。事实上,在python中,协议更像是一种指南。


容器类型的协议


1、如果定制的容器是不可变的,只需定义__len__()和__getitem__()方法。


2、如果定制的容器是可变的,除了__len__()和__getitem__()方法,还需定义__setitem__()和__delitem__()两个方法。


练习2


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


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, key):
        self.count[key] += 1
        return self.values[key]
c1 = CountList(1,3,5,7,9)
c2 = CountList(2,4,6,8,10)
print(c1[1])
print(c2[1])
print(c1[1]+c2[1])
print(c1.count)
print(c2.count)


3
4
7
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}


迭代


for i in 'FishC':
    print(i)


F
i
s
h
C


links = {'胡猪猪':'是猪',\
         '胡大猪':'shizhu',\
         '胡二猪':'是只猪',\
         '胡三猪':'zhu'}
for each in links:
    print('%s -> %s' % (each, links[each]))


胡猪猪 -> 是猪
胡大猪 -> shizhu
胡二猪 -> 是只猪
胡三猪 -> zhu


迭代器


iter()


next()


string = 'Fishc'
it = iter(string)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))


F
i
s
h
c


string = 'Fishc'
it = iter(string)
while True:
    try:
        each = next(it)
    except StopIteration:
        break
    print(each)
for each in string:
    print(each)


F
i
s
h
c
F
i
s
h
c


版本一


__iter __()


__next __()


class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1
    def __iter__(self):
        return self
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        #self.a = self.b
        #self.b = self.a + self.b
        return self.a
fibs = Fibs()
for each in fibs:
    if each < 20:
        print(each)
    else:
        break      #大于等于20跳出循环输出


1
1
2
3
5
8
13   #等于前两个数相加


版本二


class Fibs:
    def __init__(self, n = 10):
        self.a = 0
        self.b = 1
        self.n = n                 #与上个程序相比多了这个
    def __iter__(self):
        return self
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.n:        #多了这个
            raise StopIteration    #大于10生成错误输出
        return self.a
fibs = Fibs()
for each in fibs:
    if each < 20:
        print(each)
    else:
        break


1
1
2
3
5
8


版本三


class Fibs:
    def __init__(self, n = 10):
        self.a = 0
        self.b = 1
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.n:
            raise StopIteration
        return self.a
fibs = Fibs(100)      #这个不一样
for each in fibs:
    print(each)       #没有了if-else


1
1
2
3
5
8
13
21
34
55
89
目录
相关文章
|
11天前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
2月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
1天前
|
开发者 Python
Python入门:8.Python中的函数
### 引言 在编写程序时,函数是一种强大的工具。它们可以将代码逻辑模块化,减少重复代码的编写,并提高程序的可读性和可维护性。无论是初学者还是资深开发者,深入理解函数的使用和设计都是编写高质量代码的基础。本文将从基础概念开始,逐步讲解 Python 中的函数及其高级特性。
Python入门:8.Python中的函数
|
1天前
|
存储 索引 Python
Python入门:6.深入解析Python中的序列
在 Python 中,**序列**是一种有序的数据结构,广泛应用于数据存储、操作和处理。序列的一个显著特点是支持通过**索引**访问数据。常见的序列类型包括字符串(`str`)、列表(`list`)和元组(`tuple`)。这些序列各有特点,既可以存储简单的字符,也可以存储复杂的对象。 为了帮助初学者掌握 Python 中的序列操作,本文将围绕**字符串**、**列表**和**元组**这三种序列类型,详细介绍其定义、常用方法和具体示例。
Python入门:6.深入解析Python中的序列
|
1天前
|
程序员 UED Python
Python入门:3.Python的输入和输出格式化
在 Python 编程中,输入与输出是程序与用户交互的核心部分。而输出格式化更是对程序表达能力的极大增强,可以让结果以清晰、美观且易读的方式呈现给用户。本文将深入探讨 Python 的输入与输出操作,特别是如何使用格式化方法来提升代码质量和可读性。
Python入门:3.Python的输入和输出格式化
|
1天前
|
机器学习/深度学习 人工智能 算法框架/工具
Python入门:1.Python介绍
Python是一种功能强大、易于学习和运行的解释型高级语言。由**Guido van Rossum**于1991年创建,Python以其简洁、易读和十分工程化的设计而带来了庞大的用户群体和丰富的应用场景。这个语言在全球范围内都被认为是**创新和效率的重要工具**。
Python入门:1.Python介绍
|
1天前
|
缓存 算法 数据处理
Python入门:9.递归函数和高阶函数
在 Python 编程中,函数是核心组成部分之一。递归函数和高阶函数是 Python 中两个非常重要的特性。递归函数帮助我们以更直观的方式处理重复性问题,而高阶函数通过函数作为参数或返回值,为代码增添了极大的灵活性和优雅性。无论是实现复杂的算法还是处理数据流,这些工具都在开发者的工具箱中扮演着重要角色。本文将从概念入手,逐步带你掌握递归函数、匿名函数(lambda)以及高阶函数的核心要领和应用技巧。
Python入门:9.递归函数和高阶函数
|
1天前
|
存储 SQL 索引
Python入门:7.Pythond的内置容器
Python 提供了强大的内置容器(container)类型,用于存储和操作数据。容器是 Python 数据结构的核心部分,理解它们对于写出高效、可读的代码至关重要。在这篇博客中,我们将详细介绍 Python 的五种主要内置容器:字符串(str)、列表(list)、元组(tuple)、字典(dict)和集合(set)。
Python入门:7.Pythond的内置容器
|
1天前
|
存储 Linux iOS开发
Python入门:2.注释与变量的全面解析
在学习Python编程的过程中,注释和变量是必须掌握的两个基础概念。注释帮助我们理解代码的意图,而变量则是用于存储和操作数据的核心工具。熟练掌握这两者,不仅能提高代码的可读性和维护性,还能为后续学习复杂编程概念打下坚实的基础。
Python入门:2.注释与变量的全面解析
|
28天前
|
人工智能 自然语言处理 算法
随机的暴力美学蒙特卡洛方法 | python小知识
蒙特卡洛方法是一种基于随机采样的计算算法,广泛应用于物理学、金融、工程等领域。它通过重复随机采样来解决复杂问题,尤其适用于难以用解析方法求解的情况。该方法起源于二战期间的曼哈顿计划,由斯坦尼斯拉夫·乌拉姆等人提出。核心思想是通过大量随机样本来近似真实结果,如估算π值的经典示例。蒙特卡洛树搜索(MCTS)是其高级应用,常用于游戏AI和决策优化。Python中可通过简单代码实现蒙特卡洛方法,展示其在文本生成等领域的潜力。随着计算能力提升,蒙特卡洛方法的应用范围不断扩大,成为处理不确定性和复杂系统的重要工具。
69 21

热门文章

最新文章

推荐镜像

更多