Python的面向对象2

1、面向对象

  1、面向对象的结构

class A:

    company_name = ''  # 静态变量(静态字段)
    __iphone = ''  # 私有静态变量(私有静态字段)


    def __init__(self,name,age): #特殊方法

        self.name = name  #对象属性(普通字段)
        self.__age = age  # 私有对象属性(私有普通字段)

    def func1(self):  # 普通方法
        pass

    def __func(self): #私有方法
        print("哈哈")


    @classmethod  # 类方法
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')

    @staticmethod  #静态方法
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print('静态方法')

    @property  # 属性
    def prop(self):
        pass

  2、面向对象的私有与公有

#对于每一个类的成员而言都有两种形式:
#    公有成员,在任何地方都能访问,
#    私有成员,只有在类的内部才能方法
#私有成员和公有成员的访问限制不同:
#静态字段(静态变量)
#    公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
#    私有静态字段:仅类内部可以访问;
#总结:
#对于这些私有成员来说,他们只能在类的内部使用,不能再类的外部以及派生类中使用.
#ps:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!
#为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.

2、方法

  方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

class Student:
    def __init__(self,name,age):
        self.__name = name  #对象的私有方法
        self.__age = age
    #普通的实例方法
    def play(self):
        print(self.__name+"来玩啊")
    #类方法,在不需要对象参与的方法中,可以使用类方法
    @classmethod
    def high(cls):
        print("你身高多高?")
  #静态方法,该方法和对象和类都没有关系,就是一个普通的函数
    @staticmethod
    def wahahaha():
        print("谁都管不着我")

3、属性

  1、property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

  2、将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

  3、由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

class Foo:
    @property
    def HAHA(self):
        print('get的时候运行我啊')

    @HAHA.setter
    def HAHA(self,value):
        print('set的时候运行我啊')

    @HAHA.deleter
    def HAHA(self):
        print('delete的时候运行我啊')

#只有在属性HAHA定义property后才能定义HAHA.setter,HAHA.deleter
f1=Foo()
f1.HAHA
f1.HAHA='aaa'
del f1.HAHA

或者:
class Foo:
    def get_HAHA(self):
        print('get的时候运行我啊')

    def set_HAHA(self,value):
        print('set的时候运行我啊')

    def delete_HAHA(self):
        print('delete的时候运行我啊')
    HAHA=property(get_HAHA,set_HAHA,delete_HAHA) #内置property三个参数与get,set,delete一一对应

f1=Foo()
f1.HAHA
f1.HAHA='aaa'
del f1.HAHA

4、面相对象的特殊成员及相关内置函数

  1、isinstance(obj,cls)检查是否obj是否是类 cls 的对象

class A: pass

class B(A): pass

abj = B()
print(isinstance(abj,B))  #True
print(isinstance(abj,A))  #True

#isinstance检查abj是否是B的时候,会考虑继承关系
#type(abj,B)和isinstance用法相同,当时不会考虑继承关系

  2、issubclass(sub, super)检查sub类是否是 super 类的派生类

class A: pass

class B(A): pass

abj = B()

print(issubclass(B,A)) #True

  3、enumerate函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列

语法:enumerate(sequence, [start=0])
#sequence -- 一个序列、迭代器或其他支持迭代对象。
#start -- 下标起始位置。

seasons = ['Spring', 'Summer', 'Fall', 'Winter']
list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

i = 0
seq = ['one', 'two', 'three']
for element in seq:
...     print i, seq[i]
...     i +=1
... 
#结果:0 one
#1 two
#2 three

5、反射

  1、python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)

 6、内置方法(魔术方法)

  1、__call__(self, *args, **kwargs)

    对象后面加括号,触发执行。注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass    
    def __call__(self, *args, **kwargs):
        print('__call__')

obj = Foo() # 执行 __init__
obj()       # 执行 __call__

   2、__len__(self):长度方法

    len(对象)函数,执行实际调用的是对象内的__len__函数,如果该对象没有__len__方法,则会报差错

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))

  3、__init__(self):初始化方法

#初始化方法
#1、首先开辟一块内存空间
#2、把对象空间传给self,执行init
#3、把这个对象的空间返回给该对象

  4、__new__(cls, *args, **kwargs):构造方法

    4.1、__new__方法在实例化之后,__init__之前调用

#__new__方法在实例化之后,__init__之前调用
class A:
    def __init__(self):
        self.x = 1
        print('in init function')
    def __new__(cls, *args, **kwargs):
        print('in new function')
        return object.__new__(A)

a = A()
print(a.x)

    4.2、单例模式

#单例模式
class A:
    __ISINSTANCE = None

    def __new__(cls,*args,**kwargs):
        if not cls.__ISINSTANCE:
            cls.__ISINSTANCE = object.__new__(cls)
        return cls.__ISINSTANCE

    def __init__(self,name,age):
        self.name = name
        self.age = age


a = A("张三",20)
b = A("李四",25)
print(a.name)
print(b.name)
print(a,b)

  5、__str__(self)

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '太白'
a = A()
print(a)
print('%s' % a)

#print方法相当于调用__str__
#str()相当于调用__str__
#'%s'%obj相当于调用__str__

   6、__repr__(self)

class A:
    def __init__(self):
        pass
    def __repr__(self):
        return 'haha'
a = A()
print(repr(a))
print('%r'%a)

  7、__del__(self)

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

  8、item系列

class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key时,我执行')
        self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)

  9、hash(self)

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

 

posted @ 2019-07-19 11:03  IT-凯  阅读(278)  评论(0编辑  收藏  举报