面向对象1——类的成员
面向对象三大特征:1.封装 2.继承 3.多态
opp就是可以做到分解代码、最小化代码冗余以及对现有的代码进行定制再编写程序,而不是实地修改代码,或从头开始
一、类的成员:
1.字段:普通字段,静态字段
2.方法:普通方法,类方法,静态方法
3.属性
class Person:
country = 'CN' #静态字段
__money = 99999 #私有静态字段
def __init__(self,name):
self.name = name #普通字段
self.__age = 30 #私有普通字段
def show(self): #普通方法
self.__think()
return self.__age
@classmethod #类方法
def cls_func(cls):
return cls.__money
@staticmethod
def static_func():
return 123
@property
def nature(self): #属性
return '鸽子'
def __think(self): #私有方法
return '画个圈圈'
静态字段属于类,在内存中只保留一份
普通字段属于对象,在每个对象中各自保存
普通方法属于对象,至少含有一个参数self,由对象调用
类方法由类调用,至少含有一个参数cls,
静态方法有类调用,无参数self
属性有两种定义形式,上面是使用装饰器,下面是静态字段方式
def nature(self):
return '鸽子'
na = property(nature)
公有和私有
静态私有字段, __money = 99999, 错误:Person.__money
,可以通过方法间接访问,
私有字段,self.__age = 30,错误:obj.__age
私有方法,错误:obj.__think()
ps:非要访问私有属性的话,可以通过 对象._类__属性名 obj._Person__money
self
self通常是给类中的方法的第一个参数的名称,Python会自动填入实例对象(也就是方法调用的隐含主体),不必叫self,位置是重点。
二、特殊成员(部分)
__init__ __str__ __call__ __add__ __dict__ __doc__ __name__
__getitem__ __setitem__ __delitem__
__getattr__ __setattr__
class A:
'''nothing....'''
def __init__(self,data):
self.data = data
def __str__(self,data):
return self.data
def __call__(self):
print('Hellow')
def __add__(self,other):
return self.data + other
__init__
#构造方法,每次实例创建的时候,Python会自动调用它,除了明确传入类的名称的任何参数外,还会隐形的传入新实例。
__str__
当要打印一个对象时,运行__str__
__add__
对象出现在“+”表达式中,会运行__add__
__call__
对象进行调用的时候,会运行__call__
__dict__
返回字典形式的所有类或对象中的所有成员
__doc__
返回类的描述信息
__name__
返回类名
a = A(1)
print(a) # A
a() # Hellow
print(a + 2) # 3
print(a.__dict__) # {'data': 1}
print(a.__doc__) #nothing...
print(a.__class__.__name__) # A
没有定义__dict__
和__doc__
,为什么没有报错?,也是因为所有类默认继承object;:class A(object);重新定义会覆盖原有的功能,没有什么意义。
class B:
def __init__(self,number):
self.number = number
self.dic = {'k1':1,'k2':2,'k3':3,}
def __getitem__(self, key):
return self.dic[key]
def __setitem__(self, key, value):
self.dic[key] = value
def __delitem__(self, key):
del self.dic[key]
b =B(88)
n = b['k1'] #触发 __getitem__
print(n) # 1
b['k4'] = 4 #触发 __setitem__
print(b.dic) #{'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}
del b['k2'] #触发__delitem__
print(b.dic) #{'k1': 1, 'k3': 3, 'k4': 4}
class C:
pass
c = C()
c.name = 'Sroxi'
print(c.name) # Sroxi
类C中没有进行任何定义,c.name = 'Sroxi'是如何实现的?
——触发了object的__setattr__
方法,子类中重写同样没有什么意义
class Foo:
def __init__(self):
object.__setattr__(self, 'info', {}) #在对象中设置值的本质,注意:这里info带引号
def __setattr__(self, key, value):
#c.name = 'Sroxi',触发该方法,在object中有字典这样的容器进行接收
self.info[key]=value
def __getattr__(self, item):
#c.name触发该方法,将字典中的对应的value进行返回
return self.info[item]