热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【python类】类

1.类的命名空间1简单变量和属性名称1.简单变量名(无点号):遵循函数LEGB作用域法则赋值(Xvalue):使变量成为本地变量:除非声明是全局的引用(X):LEGB搜索变量

1. 类的命名空间

1> 简单变量和属性名称
1. 简单变量名(无点号):遵循函数LEGB作用域法则
==> 赋值(X = value):// 使变量成为本地变量:除非声明是全局的
==> 引用(X):// LEGB搜索变量
2. 属性名称(点号属性名称):遵循模块和类的规则
==> 赋值(object.X = value) // 实例对象命名空间内创建、修改变量
==> 引用(object.X):// 基于类的对象:对象内遵循继承搜索;模块:对象中直接读取X(模块中存在类对象,模块没有继承的概念)
2> 命名空间组成:命名空间字典和命名空间链接
属性点号运算实际是内部字典的取值; // x.data = x.__dict__['data']
x.__dict__ // 获取实例的命名空间
x.__class__ // 获取实例的父类
sub.__bases__ // sub类的父类
命名空间链接:当前命名空间找不到,会按照继承搜索查找
"""
父类层次:
B: B --> A
F: F --> D --> B --> A --> C --> A --E
"""
class A: pass
class B(A): pass
class C(A): pass
class D(B,C): pass
class E: pass
class F(D,E): pass

2. 继承

*继承原理:实际也是继承树的应用,子类实例总是先去查找自己的命名空间,然后才去查找父类命名空间*
class Manager(Person):
# 7 调用父类的构造函数:我们可以决定哪些参数使用父类,比如此处的Job
def __init__(self,name,pay):
Person.__init__(self,name,'mgr',pay)
def givePay(self,percent,bouns=.10):
# 调用方法两种方式 1) 实例.方法() 2)类.方法(self) 不管哪种,方法都需要传递一个self调用
Person.givePay(self,percent + bouns)
# 6.2 继承:扩展子类行为,只能在子类实例对象使用
def doSomething(self):
return '[%s %s]' %(self.__class__.__name__,"考核")
"""
# coding:utf-8
"""
类的继承
"""
class Employees:
def __init__(self,name,salary=0):
self.name = name
self.salary = salary
def givePay(self,percent):
self.salary = self.salary + (self.salary * percent)
def work(self):
print(self.name,"does stuff")
def __repr__(self):
return "" %(self.name,self.salary)
class Chef(Employees):
def __init__(self,name):
Employees.__init__(self,name,50000)
def work(self):
print(self.name,'make foods')
class Server(Employees):
def __init__(self,name):
Employees.__init__(self,name,40000)
def work(self):
print(self.name,'interfaces to customer')
class PizzaRobbt(Chef):
def __init__(self,name):
Chef.__init__(self,name)
def work(self):
print(self.name,'make pizza')
if __name__ == "__main__":
# 一定要分清楚:object.attr 和 赋值
# 继承是从点号运算开始的,触发实例、类以及超类中属性搜索
bob = PizzaRobbt('bob')
print(bob)
bob.work()
bob.givePay(0.2)
print(bob)
for kclass in Employees,Chef,Server,PizzaRobbt:
# kclass.__name__ 是一个字符串
obj = kclass(kclass.__name__)
obj.work()
"""
"""
"""
类的组合:order下单包含Server、Customer、PizzaRobbt一起完成一件事情.
"""
from employees import Server,PizzaRobbt
class Customer:
def __init__(self,name):
self.name = name
def order(self,server):
print(self.name,"order pizza",server)
def pay(self,server):
print(self.name,'pay money',server)
class Oven:
def bake(self):
print('ovens bakes')
class PizzaShop:
def __init__(self):
self.server = Server('Pat')
self.chef = PizzaRobbt('bob')
self.oven = Oven()
def order(self,name):
customer = Customer(name)
customer.order(self.server)
self.chef.work()
self.oven.bake()
customer.pay(self.server)
if __name__ == "__main__":
scene = PizzaShop()
scene.order('tom')
"""

3. 抽象超类

*父类中的方法具体在子类中实现;抽象超类是不能被继承的,除非所有抽象方法都在子类实现*
"""
class Super:
def method(self):
print("in Super.method")
def delegate(self):
self.action()
# 要是子类没有提供action,那么就会抛错:采用assert
# assert False,'action must be method!'
class Provider(Super):
def method(self):
print('starting Sub.method')
Super.method(self) // 扩展父类的方法
print('ending Sub.method')
def action(self): // 实现父类的抽象方法
print('In Provider.action')
"""

4. 运算符重载

# coding:utf-8
"""
运算符重载
"""
import operator
class Number:
# 1. 拦截构造方法
def __init__(self,data):
self.data = data
# 2. 拦截减法运算
def __sub__(self, other):
return Number(self.data - other)
class Indexer:
def __init__(self,data):
self.data = data
# 3.1 拦截索引、切片操作:实例对象拥有索引、切片操作
# 3.1 重载迭代:每次迭代实例对象时都会调用该方法,传入索引值
def __getitem__(self, item):
print('getitem:',item)
return self.data[item]
# 3.2 拦截索引赋值、切片赋值操作:实例对象拥有索引赋值、切片赋值操作
def __setitem__(self, key, value):
self.data[key] = value
class Squeres:
"""
iter() 迭代器工厂函数
__iter__() 迭代器协议,可以在自定义类里面形成迭代器 调用方式 1:手动next(i)调用 2:可迭代环境调用
可迭代对象:可以用迭代环境循环的对象
迭代器:支持迭代协议(也就是可以使用next调用);迭代器是可以记住状态的
可迭代对象不一定是迭代器 (for i in 'spam':)
迭代器一定是可迭代对象(支持在迭代环境循环调用)
"""
def __init__(self,start,stop):
self.value = start - 1
self.stop = stop
# 3.3 在任何迭代环境中,会优先调用__iter__;之后调用__getitem__
# __iter__调用迭代协议;__getitem__调用索引取值,知道抛出索引超范
# __iter__ 根本没有重载索引表达式:X = Squeres(1,5) X[1] 报错
# __iter__ 只循环一次: X = Squeres(1,5) [for i in X] ==> 第二次迭代会为空
def __iter__(self): # 定义了__iter__的方法,类实例是可迭代对象
return self # 此处返回self,每次生成的可迭代对象只能调用一次
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value
# 调用next方法
class SkipIterator:
def __init__(self,wrapper):
self.wrapper = wrapper
self.offset = 0
def __next__(self):
if self.offset >= len(self.wrapper):
raise StopIteration
item = self.wrapper[self.offset]
self.offset += 2
return item
# 返回迭代器对象
class SkipObject:
def __init__(self,wrapper):
self.wrapper = wrapper
def __iter__(self):
return SkipIterator(self.wrapper)
class Iter1:
"""
1. 成员关系:contains(映射) --> iter --> getitem
2. __iter__和__getitem__ 都可捕获迭代环境
区别:1 __iter__ 使用迭代协议获取值(__next__),且可以保持状态信息;__getitem__ 使用索引获取值
2 __getitem__ 可以支持索引和切片操作
3 当字段索引行数据时(list、tuple),两者可替换;为hash类型时(dict、set),只能用__iter__
"""
def __init__(self,value):
self.value = value
def __getitem__(self, item):
print("getitem:",item)
return self.value[item]
def __iter__(self):
print("iter=>",end="")
self.offset = 0
return self
def __next__(self):
print("next:",end="")
if self.offset == len(self.value):
raise StopIteration
item = self.value[self.offset]
self.offset += 1
return item
def __contains__(self, item):
print("contanins: ",end='')
return item in self.value
class Library(object):
def __init__(self):
self.books = {'title': 'a', 'title2': 'b', 'title3': 'c', }
def __getitem__(self, i):
return self.books[i]
def __iter__(self):
# 方法1 使用生成器
for titles in self.books:
yield self.books[titles]
class Empty:
"""
拦截属性点号操作;
如果python可以在继承树(self.__dict__)找到该属性,那么__getattr__方法不会被调用
赋值:self.attr = value ==> self.__setattr__(attr,value)
"""
def __init__(self):
self.data = 0
def __getattr__(self, item):
if item == "age":
print("__getattr__:",item,end=" ")
return 40
else:
raise AttributeError(item)
def __setattr__(self, key, value):
if key == "data":
# 此处一定用self.__dict__[key] = value
# 因此在__setattr__里面赋值,会再调用__setattr__,造成内存溢出
self.__dict__[key] = value
else:
raise AttributeError(key + "not allowed")
class A:
"""
1.
__add__ 原处加法(a + b ;a += 1)
__radd__ 右侧加法
2.
a + b ,python会先去a里面找__add__,找不到会去__radd__查找
这个例子: b + a 会报错,因为python会先去B找__add__,然后去A找__radd__,均不满足
3. 每个二元运算符都支持:包括 __sub__(减法)
"""
def __init__(self,val):
self.val = val
def __add__(self, other):
return self.val + other
class B:
def __init__(self,val):
self.val = val
def __radd__(self, other):
return self.val + other
class Callee:
"""
编写api接口常用:可以将类和实例调用当作函数来使用,并且可以将实例的状态保留到函数内部,自然而然成为了被一个函数记住
==>并调用另一个函数的实现
__call__ 任何定义了该方法的类和实例 支持与常规函数一致的调用
c = Callee()
c(1,2,3) ==> __call__ (1,2,3) {}
"""
def __call__(self, *args, **kwargs):
print("__call__,",args,kwargs)
class CallBack:
def __init__(self,color):
self.color = color
def __call__(self):
print('turn',self.color)
class BiJiao:
"""
比较:__lt__ __gt__ __cmp__(python3.0失效,使用operator替代)
"""
pass
class Bool1:
"""
拦截布尔操作
__bool__ >> __len__
python 3.0 优先尝试__bool__ python 2.6优先尝试__len__
"""
def __bool__(self):
return True

推荐阅读
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
author-avatar
手机用户2502870065
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有