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
目录
相关文章
|
9天前
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
10天前
|
Python
深入理解Python装饰器:从入门到实践####
本文旨在通过简明扼要的方式,为读者揭开Python装饰器的神秘面纱,从基本概念、工作原理到实际应用场景进行全面解析。不同于常规的摘要仅概述内容概要,本文将直接以一段精炼代码示例开篇,展示装饰器如何优雅地增强函数功能,激发读者探索兴趣,随后深入探讨其背后的机制与高级用法。 ####
40 11
|
7天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
7天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
7天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
13天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
49 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
WK
|
23天前
|
Python
Python中format_map()方法
在Python中,`format_map()`方法用于使用字典格式化字符串。它接受一个字典作为参数,用字典中的键值对替换字符串中的占位符。此方法适用于从字典动态获取值的场景,尤其在处理大量替换值时更为清晰和方便。
WK
68 36
|
6天前
|
设计模式 缓存 开发框架
Python中的装饰器:从入门到实践####
本文深入探讨了Python中装饰器的工作原理与应用,通过具体案例展示了如何利用装饰器增强函数功能、提高代码复用性和可读性。读者将学习到装饰器的基本概念、实现方法及其在实际项目开发中的实用技巧。 ####
19 3
|
9天前
|
机器学习/深度学习 数据采集 数据可视化
Python在数据科学中的应用:从入门到实践
本文旨在为读者提供一个Python在数据科学领域应用的全面概览。我们将从Python的基础语法开始,逐步深入到数据处理、分析和可视化的高级技术。文章不仅涵盖了Python中常用的数据科学库,如NumPy、Pandas和Matplotlib,还探讨了机器学习库Scikit-learn的使用。通过实际案例分析,本文将展示如何利用Python进行数据清洗、特征工程、模型训练和结果评估。此外,我们还将探讨Python在大数据处理中的应用,以及如何通过集成学习和深度学习技术来提升数据分析的准确性和效率。
|
8天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。