面向对象1——类的成员

面向对象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]
posted @ 2019-09-21 22:50  Sroxi  阅读(131)  评论(0编辑  收藏  举报