#   对象的基本理论
# 什么是对象?
# 万物皆对象
# 对象是具体物体
# 拥有属性
# 拥有行为
# 把很多零散的东西,封装成为一个整体
# 举例:王二小
# 属性
# 姓名
# 年龄
# 身高
# 体重
# 行为
# 走路
# 吃饭
# 放羊
# Python中的体现
# 是一门特别彻底的面向对象编程(OOP)的语言
# 其他语言:基本数据类型,对象类型
# python全部类型都是对象类型
# 面向对象是面向过程的封装
# 对象和类的关系:对象 可以抽象为类 类可以实例化为对象 class Money:
pass print(Money) #<class '__main__.Money'>
one = Money()
print(one, type(one)) #<__main__.Money object at 0x030CFBB0> <class '__main__.Money'> class Person:
pass # 对象的操作:增
p = Person()
# 查看对象的所有属性
print(p.__dict__) #{}
p.age = 18
p.height = 180
print(p.__dict__) #{'age': 18, 'height': 180} # 对象的操作:删
del p.age # 对象的操作:改
p.height = 185 # 对象里面如果有这个属性,就是修改,否则就是增加这个属性 # 类里面的 __dict__ 不可以修改,只读的
# 对象里的 __dict__ 可以修改
class Test:
age = 18 #Test.__dict__["age"] = 20 #TypeError: 'mappingproxy' object does not support item assignment one = Test() one.__dict__ = {"name":"abc", "height":180} # __dict__字典里面生存储属性的变量
print(one.__dict__) #{'name': 'abc', 'height': 180} # 理解下面的内容
class Person:
age = 10 p = Person() print(Person.age) #
print(p.age) # p.age += 5 # p.age = p.age + 5
# 要理解这个在对象和类的操作方法:首先是计算右边的值,p.age 在对象p中没有,所以他要到类中去取age = 10
# 然后变成10+5 = 15, 然后在p对象中新增加个age属性(以前说过,对象没有就是新增,有的话就是修改) print(Person.age) #
print(p.age) # # __slots__
class Person:
__slots__ = {"age"} #只能加入age的属性 p1 = Person()
p1.age = 18
print(p1.age) # 方法:实例方法,类方法,静态方法 class Person:
def eat(self):
print("这是个实例方法", self) @classmethod
def eat2(cls):
print("这是个类方法", cls) @staticmethod
def eat3():
print("这是个静态方法") p = Person()
print(p)
p.eat()
p.eat2()
p.eat3()
# <__main__.Person object at 0x032F54F0>
# 这是个实例方法 <__main__.Person object at 0x032F54F0>
# 这是个类方法 <class '__main__.Person'>
# 这是个静态方法
print("-" * 30)
#另外的调用方式:
Person.eat("") #这里必须要有个参数,才能调用成功
Person.eat2()
Person.eat3() print("-" * 30) # 实例方法,类方法,静态方法的访问权限问题(包括类属性,实例属性)
class Person:
age = 10
# 实例方法
def shilie(self):
print(self)
print(self.age)
print(self.num) # 类方法
@classmethod
def leifangfa(cls):
print(cls)
print(cls.age)
print(cls.num) # 不可以使用实例属性 # 静态方法
@staticmethod
def jingtai():
print(Person.age) # 能使用类里面的属性,但很少这样去调用的 p = Person()
p.num = 11 p.shilie() # 实例方法:可以调用实例属性和类属性
#p.leifangfa() # 类方法:不可以使用实例属性
p.jingtai() # 静态方法:可以使用类属性,不可以使用实例属性 # 元类
num = 123
str = "abc"
print(num.__class__.__class__) # <class 'type'>
print(str.__class__.__class__) # <class 'type'>
print(Person.__class__) # <class 'type'>
print(Person.__class__.__class__)# <class 'type'>
print(p.__class__.__class__) # <class 'type'> # ----------------------------另外一种创建类的方式-------------------------
def run(self):
print(self) dog = type("Dog",(),{"name":"abc","run":run}) #字典里面可以是类属性,或者类方法
print(dog.name) #abc
print(dog.run) #<function run at 0x02B56C90> # ---------------------------类的创建流程---------------------------------- class Animal:
# __metaclass__ = xxx
pass class Person(Animal):
# __metaclass__ = xxx
pass # -------------------------类的描述, pydoc 模块---------------------------------------
class Person:
"""
关于类的描述,类的左右,类的构造函数
Attribute:
属性的描述
"""
def run(self, distence, step):
"""
函数的作用
:param distence:参数含义,数据类型,默认值
:param step:
:return: 返回值类型
"""
return distence / step # help(Person) # 可以这样看帮助文档 # ------------------------ 私有化属性(类的内部,子类内部,模块内部,模块外部)4大块 ------- class Animal:
x = 10
_y = 20
__z = 30
def test(self):
print(Animal.x)
print(self.x)
print(Animal._y)
print(self._y)
print(Animal.__z)
print(self.__z)
print("-" * 30) class Dog(Animal):
def test2(self):
print(Dog.x)
print(self.x)
print(Dog._y)
print(self._y)
# print(Dog.__z) # 错误
# print(self.__z) # 错误
print("-" * 30) # 类的内部访问
a = Animal()
a.test() # 成功打印x # 子类的内部访问
d = Dog()
d.test2() # 成功打印x # 模块内部访问
# print(Animal.x) # 成功打印x
# print(Dog.x) # 成功打印x
# print(a.x) # 成功打印x
# print(d.x) # 成功打印x
# print(a.__z) # 有错误
#
# print(Animal._y) # 成功打印_y,但有警告
# print(Dog._y) # 成功打印_y,但有警告
# print(a._y) # 成功打印_y,但有警告
# print(d._y) # 成功打印_y,但有警告
# print(a.__z) # 有错误
# print(d.__z) # 有错误 print(Animal.__dict__)
print(Animal._Animal__z) # 伪私有 30
# 模块外的访问
import public
print(public.num) # 成功打印num
print(public._num2) # 另外一种模块导入方法
from public import *
# 直接写public 模块中的变量
print(num) # 成功打印num
# print(_num2) # 有错误 # ------------------------ 私有化属性应用场景 ---------------------------------
# 数据保护,数据过滤
class Person: def __init__(self):
self.__age = 18 def setAge(self, value):
if isinstance(value, int) and 0 < value < 200 :
self.__age = value
else:
print("you input data error!!!") def getAge(self):
print("you age is ", self.__age)
return self.__age p = Person()
p.setAge(100)
print(p.getAge()) # --------------- 私有化的2个规范---------------------
# 1. x_ 这样命名的主要是区分系统的关键字,但又想用这个名字,所以在下面加下划线,比如 int_, class_
# 2. __x__ 这种命名的主要是系统的内置命名功能的变量 # --------------- 只读属性-------------------------
# __x 这样在类中命名的变量,既不能在实例属性中读取和修改,除非通过间接的办法来实现;
# 比如在类中通过写个函数来读取类中的 __x 变量;如果现在来改写一下只能读取的方式;
class Person:
def __init__(self):
self.__age = 18 @property
def age(self): # 这样就可以像正常通过实例属性来访问,但却不能通过实例属性来修改和增加
return self.__age p = Person()
print(p.age) #
# p.age = 111 # AttributeError: can't set attribute
# 上面的只读属性,也不是安全的,可以通过设置__dict__来修改
# p.__dict__["_Person__age"] = 999
p._Person__age = 888
print(p.age) # # --------------新式类(python 3.xx,继承object) 和 经典类(python 2.xxx 默认形式不继承object) ----------
class Person:
pass print(Person.__bases__) # (<class 'object'>,) 3.xx默认情况 # 也可以显示的显示如下,最好这样写,可以兼容2.xx:
class Person(object):
pass print(Person.__bases__) # (<class 'object'>,) # ------------- 设置只读属性的正确方法 ---------------------------
class Person:
# 需要只读的key 列表
attr_key = ["age","name"] # 当我们通过:实例.key = value 操作的时候都会调用这个方法 __setattr__
# 在这个方法的内部,在会把key : value 这些值存储到__dict__对象里面
def __setattr__(self, key, value):
print(key, value)
if key in self.attr_key and key in self.__dict__.keys() :
print("this is {} attrute only read ".format(key))
else:
# self.key = value # 这样写会有问题,涉入死循环
self.__dict__[key] = value p = Person()
p.age = 18 #执行到这里,就会打印 age 18
print(p.age) #
print(p.__dict__) # {'age': 18} p.age = 19 # 这里赋值后就会提示上面的错误 this is age attrute only read # --------------------------内置特殊属性----------------------
#类属性
# __dict__ 类的属性
# __bases__ 类的所有父类构成的属性
# __doc__ 类的文档字符串
# __name__ 类名
# __module__ 类定义中的模块
# __str__ 类定义字符串
#__call__ 实例直接调用 p() #实例属性
# __dict__ 实例属性
# __class__ 实例属性对应的类 class Person:
def __call__(self, *args, **kwargs):
print(args,kwargs) def __str__(self):
return "这个是个人类的类(字符串)" def __repr__(self):
return "这是个_repr_" p = Person()
p() # 类中有了__call__,就可以这样调用了,打印() {}
p("","abc", name="cctv") #('123', 'abc') {'name': 'cctv'} print(p.__str__()) #这个是个人类的类(字符串)
print(p) #这个是个人类的类(字符串)
print(p.__repr__()) #这是个_repr_
print(repr(p)) #这是个_repr_ # ------------------------ 索引操作 -------------------------------- class Person:
def __init__(self):
self.cache = {} def __setitem__(self, key, value):
print(key, value)
self.cache[key] = value def __getitem__(self, key):
print(key)
return self.cache[key] def __delitem__(self, key):
print(key)
del self.cache[key] p = Person()
p["name"] = "abc"
print(p["name"])
del p["name"] print(p.cache) #{} # --------------------- 比较操作 -----------------------------------
class Person:
# == ,!= , >, >= , < , =<
def __init__(self, age, height):
self.age = age
self.height = height def __eq__(self, other):
# print(self.age, other.age)
return self.age == other.age def __ne__(self, other):
return self.age != other.age def __gt__(self, other): #大于
pass def __ge__(self, other): #大于等于
pass def __lt__(self, other): #小于
pass def __le__(self, other): #小于等于
pass p1 = Person(18, 180)
p2 = Person(18, 190)
print(p1 == p2) # True print(p1 != p2 ) # False # -------------------- 上下文的布尔判断 -----------------------------
class Person:
def __init__(self):
self.age = 19 def __bool__(self):
return self.age >= 18 p1 = Person()
if (p1):
print("p Ture") # p Ture # --------------------遍历操作 --------------------------------------
class Person:
def __init__(self):
self.result = 0 # 和上面的索引操作一样
def __getitem__(self, item):
self.result += 1
if (self.result > 5 ):
raise StopIteration("停止遍历")
return self.result # 这个要优先于__getitem__ 运行
def __iter__(self):
self.result = 0 # 迭代器次重复使用
return self def __next__(self):
self.result += 1
if (self.result > 5):
raise StopIteration("next停止遍历")
return self.result p = Person()
for v in p :
print(v) # 1 2 3 4,5 # ----------------------- 描述器 ---------------------------
# 方法一:举例
class Person:
def __int__(self):
self.__age = 18 def get_age(self):
return self.__age def set_age(self, value):
if value < 0 :
value = 0
self.__age = value def del_age(self):
del self.__age # 方法一
age = property(get_age, set_age, del_age) p = Person()
p.age = 10 # 一定要赋值,不然下面调用就会错误
print(p.age) class Person:
def __int__(self):
self.__age = 18 @property
def age(self):
return self.__age
@age.setter def age(self, value):
if value < 0:
value = 0
self.__age = value @age.deleter
def del_age(self):
del self.__age p = Person()
p.age = 20 # 一定要赋值,不然下面调用就会错误
print(p.age) # -------------------方法二------------------------
class Age:
def __get__(self, instance, owner):
print("get")
return instance.v def __set__(self, instance, value):
print("set")
instance.v = value def __delete__(self, instance):
print("delete") class Person:
age = Age() p = Person()
p.age = 10
print(p.age) # -------------------使用类,实现装饰器 -----------------------
# 以前学过通过函数来实现装饰器,如:
def checkLogin(func):
def inner():
print("正在登陆认证")
func()
return inner @checkLogin
def fashuoshuo():
print("发说说") fashuoshuo() #正在登陆认证 发说说 # 现在换成类的形式
class Check:
def __init__(self, func):
self.f = func def __call__(self, *args, **kwargs):
print("正在登陆认证")
self.f() @Check
def fatupian():
print("发图片") fatupian() # 正在登陆认证 发图片 # ---------- 几个监听对象生命周期的方法-------------
class Person:
# def __new__(cls, *args, **kwargs):
# print("新建一个对象的时候, 但被我拦截了")
def __init__(self):
print("这个类被初始化了") def __del__(self):
print("这个对象被释放了") p = Person() # 新建一个对象的时候, 但被我拦截了
print(p) # None
p = Person() #这里要把 __new__ 给注释掉,不然会被拦截 # ---------- 几个监听对象生命周期的方法:小案例-------------
# Person, 打印一下,当前这个时刻,由Person类,产生的实例,有多少个
# 创建了一个实例,计数+1,如果删除了一个实例 计数-1 class Person:
__personCount = 0 def __init__(self):
self.__class__.__personCount += 1 # 和下面的Person.__personCount 的方法是一样的 def __del__(self):
# Person.__personCount -= Person.__personCount - 1 有些问题
self.__class__.__personCount -= 1
@staticmethod
def log():
# print("当前创建人的实例有{}个".format(Person.__personCount))
print("当前创建人的实例有%d个"%Person.__personCount) # 或者写成下面的形式
@classmethod
def log2(cls):
print("当前创建人的实例有%d个" % cls.__personCount) p = Person()
p2 = Person()
Person.log() # 当前创建人的实例有2个
Person.log2() # 当前创建人的实例有2个
del p2
Person.log() # 当前创建人的实例有1个
Person.log2() # 当前创建人的实例有1个 # ----------------对象 内存管理机制 存储 ---------------------
num1 = 1
num2 = 1
print(id(num1), id(num2) ) #相同数值的变量地址一样,访问的是同一个地址,这是Python的机制决定的,优化访问时间 class Person:
pass p = Person()
p2 = Person()
print(id(p), id(p2)) # 打印地址不一样 # ----------------引用计数器 ---------------------
import sys
#
class Person:
pass p1 = Person()
# 获得对象的引用次数
print(sys.getrefcount(p1)) # p2 = p1
print(sys.getrefcount(p1)) #
print(sys.getrefcount(p2)) #
del p1 del p2 # ------------- 引用计数器机制-特殊场景--循环引用问题-----------
# 内存管理机制:引用计数器机制 + 垃圾回收机制
# 当一个对象被引用时 +1, 删除一个引用 -1 ,0:自动释放
# objgraph
# objgraph.count(), 可以查看,垃圾回收器,跟踪的对象个数 import objgraph
class Person:
pass class Dog:
pass p = Person()
d = Dog() p.pet = d
d.master = p
print(objgraph.count("Person")) #
print(objgraph.count("Dog")) # del p
del d
print(objgraph.count("Person")) # 1 这样就造成了内存泄露
print(objgraph.count("Dog")) # # --------------内存管理机制 垃圾回收 如何检测循环引用 -----------
# --------------垃圾回收机制 分代回收 ------------
# --------------垃圾回收机制中 新增的对象个数 - 消亡的对象个数 达到一定个数才会触发垃圾检测
import gc
#查看阀值,700个对象,10次
print(gc.get_threshold()) # (700, 10, 10)
gc.set_threshold(200,5,5) # 设置参数
print(gc.get_threshold()) # (200, 5, 5) # --------------垃圾回收机制 触发时机(自动,和手动)
import gc # 自动回收
# 查看垃圾回收机制是否开启,默认是开启的
print(gc.isenabled()) # True
# 达到一定的阀值才会执行
# 关闭垃圾回收机制
gc.disable() # 手动回收
import gc
import objgraph class Person:
pass class Dog:
pass p = Person()
d = Dog() p.pet = d
d.master = p del p
del d
gc.disable() #关闭垃圾回收后,下面语句也有效果
# 通过“引用计数器机制”无法回收;需要借助“垃圾回收机制”进行回收
gc.collect() # 参数有:空,0,1,2 空代表全部代的回收,0,代表0代回收,2,代表0,1,2代都回收
# 查看
print(objgraph.count("Person")) #
print(objgraph.count("Dog")) #

Python 对象学习一的更多相关文章

  1. python对象学习

    python对象的介绍 python使用对象模型来存储数据,构造任何类型的值都是一个对象,尽管python被当成面向对象的编程语言,但是完全编写不使用任何类和实例的脚本.所有的python对象都拥有三 ...

  2. 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习

     孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...

  3. PyQt(Python+Qt)学习随笔:Qt Designer中窗口对象的windowFilePath属性

    windowFilePath属性仅对窗口对象有效,用于关联一个窗口和对应的文件及路径. 当窗口没有设置标题属性的情况下,则窗口标题展示展示windowFilePath对应的文件名的信息(路径信息不展示 ...

  4. #python基础学习模块:marshal 对象的序列化

    #标准库地址:https://docs.python.org/2/library/marshal.html"""有时候,要把内存中一个对象持久化保存磁盘或者序列化二进制流 ...

  5. python学习笔记:python对象

    一.python对象 python使用对象模型来存储数据,构造任何类型的值都是一个对象.所有的python对象都拥有三个特性:身份.类型和值. 身份:每个对象都有一个唯一的身份标识自己,对象的身份可以 ...

  6. 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL

    周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...

  7. python爬虫学习(1) —— 从urllib说起

    0. 前言 如果你从来没有接触过爬虫,刚开始的时候可能会有些许吃力 因为我不会从头到尾把所有知识点都说一遍,很多文章主要是记录我自己写的一些爬虫 所以建议先学习一下cuiqingcai大神的 Pyth ...

  8. Python正则表达式学习摘要及资料

    摘要 在正则表达式中,如果直接给出字符,就是精确匹配. {m,n}? 对于前一个字符重复 m 到 n 次,并且取尽可能少的情况 在字符串'aaaaaa'中,a{2,4} 会匹配 4 个 a,但 a{2 ...

  9. Python 多线程学习(转)

    转自:http://www.cnblogs.com/slider/archive/2012/06/20/2556256.html 引言 对于 Python 来说,并不缺少并发选项,其标准库中包括了对线 ...

随机推荐

  1. python技巧之下划线(二)

    Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用’from module import *’导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划 ...

  2. iOS UITextView 输入内容实时更新cell的高度

    iOS UITextView 输入内容实时更新cell的高度 2014-12-26 11:37 编辑: suiling 分类:iOS开发 来源:Vito Zhang'blog  11 4741 UIT ...

  3. ZOJ 3941 Kpop Music Party(省赛, 贪心)

    Kpop Music Party Time Limit: 2 Seconds      Memory Limit: 65536 KB Marjar University often hosts Kpo ...

  4. <td></td>之间的&nbsp;

    今天开发中遇到了一个很丢脸的事:我把下图中别人写的 给去掉了,我觉得这个很多余,结果被在大神们痛斥了一顿.因为去掉这个 会导致td之间没有数据时td的边框不显示的问题,所以几下这个惨痛的教训,以自警. ...

  5. Oracle Schema Objects——Tables——TableType

    Oracle Schema Objects Object Tables object type An Oracle object type is a user-defined type with a ...

  6. 使用ServiceStack缓存技术

    ServiceStack 是一个高性能的 .NET Web 服务框架,简化了开发 XML.JSON.JSV 和 WCP SOAP Web 服务.它定义了符合 Martin Fowlers 数据传输对象 ...

  7. The Ultimate Guide To A/B Testing

    w http://blog.jobbole.com/25576/?utm_source=blog.jobbole.com&utm_medium=relatedPosts https://www ...

  8. 常用的SQLalchemy 字段类型

    https://blog.csdn.net/weixin_41896508/article/details/80772238 常用的SQLAlchemy字段类型 类型名 python中类型 说明 In ...

  9. ArcGIS runtime sdk for wpf 授权

    这两天由于runtime sdk for wpf的授权和runtime sdk 其他产品的授权的不一样导致自己混乱不堪. 总结下吧. sdk 简介 当前ArcGIS runtime sdk 包括一系列 ...

  10. Runtime Error! R6025-pure virtual function call 问题怎么解决

    一.故障现象:1.360软件的木马查杀.漏洞修复等组件不能使用,提示runtime error2.暴风影音等很多软件不能正常使用3.设备管理器不能打开,提示“MMC 不能打开文件”4.部分https安 ...