热门标签 | 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

推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 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的使用方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
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社区 版权所有