面向对象进阶:类成员、类成员的修饰符、类的特殊成员

类成员

类成员分为三大类:字段、方法、属性

一、字段

  • 静态字段 (属于类)
  • 普通字段(属于对象)
 class City:
# 静态字段
country = "中国" def __init__(self,city_name):
# 普通字段
self.city_name = city_name def show(self):
print(self.city_name) obj1 = City("Harbin")
obj2 = City("Shanghai")
# 普通字段对象来访问
print(obj1.city_name,obj2.city_name)
# 静态字段通过类名访问
print(City.country)

字段

内存中分布:

  1. 静态字段在内存中只保存一份
  2. 普通字段在每个对象中都要保存一份

静态字段定义及应用:随着这个程序的执行产生,随着程序的结束而消失,这样和程序‘共存亡’的字段,我们就叫它静态字段。它就像是一个全局变量,不属于任何一个对象,我们可以直接使用类来调用,也可以在对象使用方法的时候使用它。它是对象共享的变量,存在类的内存里。

特殊:对象也可以访问静态字段。静态字段在代码加载时已经创建。

遵循规则:普通字段只能对象访问;静态字段用类访问。(万不得已用对象访问)

二、方法

  • 静态方法:由调用;无默认参数;
  • 类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls
  • 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
 class Province:

     country = "China"
def __init__(self,name):
self.name = name # 普通方法 由对象调用。
def show(self):
print(self.name) # 静态方法 ,无self参数;方法前边加上关键字@staticmethod 由类调用
@staticmethod
def display(a,b,c):
print(a,b,c) # 类方法(相当于静态方法特殊形式),至少要有一个cls参数。由类调用
@classmethod
def listen(cls,b):
'''
cls:类名
'''
print(cls.country,b) obj = Province("黑龙江")
obj.show() # 普通方法由对象调用
Province.display(1,2,3) # 静态方法由类调用执行
Province.listen(2) # cls是python自动传递

方法

三、属性

  • 属性的基本使用
 class Page:

     def __init__(self,all_counts):
self.all_counts = all_counts # 属性: 分页
@property
def divpages(self):
a,b = divmod(self.all_counts,10)
if b == 0:
return a
else:
return a+1 p = Page(101)
ret = p.divpages# 调用属性 直接返回
print(ret)

属性的定义和调用:

  • 定义时,在普通方法的基础上添加 @property 装饰器;
  • 定义时,属性仅有一个self参数
  • 调用时,无需括号
               属性:p.divpages

Python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回

注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。

 class Page:

     def __init__(self,all_counts):
self.all_counts = all_counts # 属性: 分页
@property
def divpages(self):
a,b = divmod(self.all_counts,10)
if b == 0:
return a
else:
return a+1
# 设置属性:支持赋值操作
@divpages.setter
def divpages(self,value):
self.all_counts = value
# 删除
@divpages.deleter
def divpages(self):
print("del property")
p = Page(101)
p.divpages = 111 #自动执行 @divpages .setter 修饰的 divpages 方法,并将 123 赋值给方法的参数
ret = p.divpages # 自动执行 @property 修饰的 divpages方法,并获取方法的返回值
del p.divpages # 自动执行 @divpages.deleter 修饰的 divpages方法
print(ret)

属性操作:不同属性调用形式,触发不同装饰器的方法,见下图。

  • 属性另一种表达方式
class Page:

    def __init__(self,count):
self.count = count def f1(self):
return 123 def f2(self):
print("fset:赋值") def f3(self):
print("fdel:删除") foo = property(fget=f1,fset=f2,fdel=f3) p = Page(100)
ret = p.foo # 自动回找到fool,会找到fget对应函数f1并执行,并将返回值
p.foo =113 #会找到fset对应函数f2并执行
del p.foo # 会找到fdel并执行f3

类成员修饰符

  • 公有:在类内和类外均可以访问
  • 私有:仅在类的内部可以访问;私有成员命名时,前两个字符是下划线
  1. 公有字段和私有字段
 class Person:
# 私有 静态字段
__school = "北大"
def __init__(self,name,sex):
# 普通字段,公有,name ;私有 sex
self.name = name
self.__sex = sex # 均可在类内调用
def f1(self):
print(self.name)
print(self__sex) def f2(self):
print(Person.__school) class ChianPerson(Person):
def f2(self):
print(self.__sex) obj = Person("lcy","man")
print(obj.name) # 类外访问公有普通字段
# print(obj.__sex) # 无法访问 报错 no attribute
#print(Person.__school) # 无法访问
obj.f3() # 打印 "北大"
# ----- 继承,派生类不能访问基类私有的普通字段-------
obj2 = ChinaPerson("alex","female")
#obj2.f2() # 执行 失败,只有Person类内方法可以访问
obj2.f1() # 可以执行f1是Person类中的方法

  2. 公有方法和私有方法

(略)

这里公有方法和私有方法与上边字段访问限制是一样的。私有方法命名同私有字段命名相同。只要在函数名前加两个下划线,就表示私有方法。

类的特殊成员

  • __init__:构造方法
  • __del__:析构方法
  • __doc__:注释类
  • __module__:对象所在模块
  • __class__:对象类名
  • __call__: obj() 或类名()触发执行
  • __str__:print(obj)自动调用
  • 其他:__add__
 class Person:
'''
这是一个人类
'''
def __init__(self,name):
self.name = name def __del__(self):
print("这是析构函数一般不自定义,python有自己的回收机制") def __call__(self, *args, **kwargs):
print("call") def __str__(self):
return ("__str__:%s"%self.name) def __add__(self, other):
print(self.name,other.name) # 创建对象,自动调用__init__
obj_p1 = Person("lcy")#
obj_p2 = Person("alex")
print(obj_p1.__doc__)
print(obj_p1.__module__)
print(obj_p1.__class__)
# 自动调用 __call__
obj_p1()
#Person("lcy")() 同 obj_p1()
# 触发__str__方法
print(obj_p1)
res = str(obj_p1)
print(res)
# 会触发 __add__ /同理会有其他的方法,加减乘除。。。
obj_p1+obj_p2
# 程序会自动调用__del__析构函数,对象在回收机制之前,这里会调用两次,因为创建了两次
  • __dict__:重点 (默认已经存在类或者对象中)

获取类成员:静态字段,方法。

 class Game:

     Game_name = "SIM3"

     def  __init__(self):
pass def show(self):
pass print(Game.__dict__)
'''
{'__init__': <function Game.__init__ at 0x00503E88>,
'show': <function Game.show at 0x00503DF8>,
'__weakref__': <attribute '__weakref__' of 'Game' objects>,
'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Game' objects>,
'Game_name': 'SIM3', '__doc__': None}
'''

对象:获取对象的字段

 class Game:

     Game_name = "SIM3"

     def  __init__(self,level,money):
self.level = level
self.money = money def show(self):
pass
obj = Game(12,199)
print(obj.__dict__)
'''
{'money': 199, 'level': 12}
'''
  • __getitem__、__setitem__、__delitem__

对象用于索引,如字典相关操作。获取、设置以及删除操作

 class Foo:

     def __getitem__(self, item):
print(item) def __setitem__(self, key, value):
print(key,value) def __delitem__(self, key):
print(key) obj = Foo()
obj["k1"] # 触发 __getitem__
obj[3] #触发 __getitem__
obj[2] = 234 # 触发__setitme
del obj[3] # 触发__delitem

支持对象切片操作。(python3 用触发上边的方法来实现)

 class Foo:

     def __getitem__(self, item):
print(type(item))
print(item.start)
print(item.stop)
print(item.step) def __setitem__(self, key, value):
print(type(key))
print(key.start,key.stop,key.step,value) def __delitem__(self, key):
print(type(key))
print(key.start,key.stop,key.step) obj = Foo()
obj[1:3:2] # 触发 __getitem__
obj[1:3:2] = [11,22,44] #触发 __setitem__
del obj[1:3:2] # 触发__delitem__
输出:

<class 'slice'>
1
3
2
<class 'slice'>
1 3 2 [11, 22, 44]
<class 'slice'>
1 3 2

 

(待续,天冷,打字都动手啊)

python之路——面向对象(进阶篇)的更多相关文章

  1. python之路 面向对象进阶篇

    一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 countr ...

  2. python之路----面向对象进阶一

    一.isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() i ...

  3. python之路——面向对象进阶

    阅读目录 isinstance和issubclass 反射 setattr delattr getattr hasattr __str__和__repr__ __del__ item系列 __geti ...

  4. python之路:进阶篇 内置函数

     li = [11, 22, 33] news = map(  li = [100, 2200, 3300] news = map(  [13, 24, 35] [11, 11, 11] [22, 4 ...

  5. python之路:进阶篇

     > ) {        ;    }    printf(;} print i >>>      >>>  == :    name  ==   ==   ...

  6. python之路----面向对象进阶二

    item系列 __getitem__\__setitem__\__delitem__ class Foo: def __init__(self,name,age,sex): self.name = n ...

  7. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  8. Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy   Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...

  9. Python之路【第九篇】:Python面向对象

    阅读目录 一.三大编程范式 编程范式即编程的方法论,标识一种编程风格: 大家学习了基本的python语法后,大家可以写python代码了,然后每个人写代码的风格不同,这些不同的风格就代表了不同的流派: ...

随机推荐

  1. Python-Numpy函数-tile函数

    tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题 ...

  2. AE IRasterCursor 改变栅格图层像素值

    1 public void ChangePixelValue(double xMax, double xMin, double yMax, double yMin,double[,] PixelCha ...

  3. oracle计算是否是同一周

    函数已经解决跨年问题 select to_char(date'2016-12-31','iW') from dual; select to_char(date'2017-01-01','iW') fr ...

  4. python 脚本中使用了第三方openpyxl 打包程序运行提示ImportError:cannot import name __version__

    最近写了一个脚本,脚本中使用了第三方openpyxl(openpyxl是使用 pip install openpyxl 下载的),先是使用py2exe打包程序,打包过程中提示很多文件没有包含,在没有仔 ...

  5. STL之容器适配器priority_queue

    priority_queue(优先队列)是一个拥有权值观念的queue,它允许加入新元素,删除旧元素,审视元素值等功能.由于这是一个queue,所以只允许在底端加入元素,并从顶端取出元素, 除此之外别 ...

  6. STL之序列式容器list与forward_list

    List (双向链表) 与 forwardlist (单向链表) 算是非常基础的数据结构了,这里只是简单介绍下其结构及应用. 以list为例: 其节点模板: template <class T& ...

  7. 我刚知道的WAP app中meta的属性

    之前我一直做的都是WEB前端开发,来北京以后面试了一个移动前端开发,WAP前端开发. 其实在原来公司的时候也做过这方面的开发,可面试的时候面试官问我,要想强制让文档与设备的宽度保持1:1,mate标签 ...

  8. oracle修改字段长度

    alter table 表名 modify (字段名 字段类型长度);alter table cachemsg modify (callernum varchar(40));

  9. jquery.validate[.unobtrusive]和Bootstrap实现tooltip错误提示

    类似的文章园子里已有,请看这里,个人感觉稍显复杂,日前也打算写一个简单的给项目用,一些关键点记录于此.最终效果如下: 后端使用Asp.net mvc5,前端框架有:jquery.validate.jq ...

  10. Android 打包

    1.数字签名(指的是我们打包程序时所用keystore的SHA1指纹) 2.debug打包,不能在android 市场上架,使用的签名是默认的签名,1年后失效:release打包使用的是自己的签名,可 ...