面对整体分为两个部分:

  静态变量部分

  方法部分

class A:

    company_name = '百度'  # 静态变量(静态字段)
    __iphone = '1353333xxxx'  # 私有静态变量(私有静态字段)


    def __init__(self,name,age): #普通方法(构造方法)

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

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

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


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

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

    @property  # 属性
    def prop(self):
        pass
类的结构细分

 

一,面向对象的私有

私有的

  --名字

    静态属性(静态字段)

    动态属性(方法)

    类方法

    静态方法

    特性

私有的特点

  只能在类的内部被调用

  不能被继承

什么时候用私有?

  当不想被外部调用也不想被继承,只想在类的内部使用的时候

  当在外部使用的时候,想给用户的使用前\后直接加上某些功能

    私有+property使用

二,面相对象的特殊成员及相关内置函数

isinstance与issubclass

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

class A: pass

class B(A): pass

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

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

class A: pass

class B(A): pass

abj = B()

print(issubclass(B,A)) #True
示例

 反射:

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩

什么是反射:用字符串类型的变量名来访问这个变量的值

反射的方法:hasattr getattr setattr delattr   (前两个比较重要)

用到的地方 : 类 ,对象,模块,反射自己的模块

类:

反射查看属性

getattr(命名空间,‘变量名’)   第一个参数的命名空间中的变量名为第二个参数的变量,并得到它的值

反射调用方法

if hasattr(命名空间,’方法名‘): #查看方法是否存在

  getattr(命名空间,‘方法名’) ()    # 可以是类方法 ,静态方法,普通方法

hasattr 和 getattr 如影相随

对象: 方法,对象属性

getattr(对象,’方法名‘)()

模块

getattr(模块,’指令‘)

例:

import os 

getattr(os,'rename')('原文件名’,‘新文件名’)

反射自己的模块

import sys   # 是一个模块,这个模块里的所有方法都是和python解释器相关

#  sys.modules 是一个字典,记录所有在当前这个python程序中导入的模块

my_file=sys.modules['__main__']    # 找到当前的命名空间

getattr(my_mile,'方法名‘)()

 

 

__名字__ 

  类中特殊方法\内置方法

  双下方法\魔术方法 (外文翻译过来的叫法)

__call__   相当于对象()

class A:
    def __call__(self, *args, **kwargs):
        print('哈哈哈')
a=A()
a()  #对象加括号就可以调用call 方法
A()()
示例

__len__ 相当于len(obj)

class A:
    def __init__(self,lis):
        self.lis=lis
    def __len__(self):
        return len(self.lis)
obj=A([1,2,3,4,5])
print(len(obj))
示例

__new__ 特别重要 开辟内存空间的 类的构造方法

class A:
    __num=None
    def __new__(cls,*args,**kwargs):
        if not cls.__num:
            cls.__num=object.__new__(cls)
        return cls.__num
    def __init__(self):
        pass
a1=A()
a2=A()
print(a1)   #打印的都是同一个对象空间
print(a2)
单例类

__str__  相当于 str(obj), '%s' % obj print(obj)

 

print一个对象相当于调用一个对象的__str__方法
str(obj),相当于执行obj.__str__方法 ,  
'%s'%obj,相当于执行obj.__str__方法

要求这个方法的返回值必须是字符串str类型

 

class Student:
    def __str__(self):
        return '%s %s %s'%(self.school,self.cls,self.name)

    def __init__(self,name,stu_cls):
        self.school = '北大'
        self.name = name
        self.cls = stu_cls

he = Student('hezewei','py14')
# print(he)
huang = Student('huangdongyang','py14')
# print(huang)
# print(str(he))   # 内置的数据类型,内置的类,相当于执行__str__
print('学生1 : %s'%he)
示例

 __repr__  

repr() ,  '%r ' % 

是__str__的备胎.如果有__str__方法,那么 print ,%s, str 都先去执行__str__方法,并且使用__str__的返回值
如果没有__str__,那么 print %s str都会执行repr
repr(obj)  ,  %r  不能用__str__ 代替,只能执行__repr__

在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就执行父类的__str__
但是如果除了object之外的父类都没有__str__方法,就执行子类的__repr__方法,如果子类也没有,
还要向上继续找父类中的__repr__方法.
一直找不到 再执行object类中的__str__方法

# class A:
#     def __init__(self,name):
#         self.name = name
#     def __str__(self):
#         return '**%s**'%self.name
#     def __repr__(self):
#         return self.name
# 
# class B(A):
#     def __repr__(self):
#         return '***'

# a = B('alex')
# print(a)
# print(str(a),repr(a))
# print('%s | %r'%(a,a))
# print('---%r---'%('abc'))
# print('---%s---'%('abc'))
示例

 __del__ 析构方法 : 释放一个空间之前执行

某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源  网络资源

# 垃圾回收机制
# class A:
#     def __del__(self):
#         # 析构方法 del A的对象 会自动触发这个方法
#         print('执行我了')
# a = A()
# del a  # 对象的删除 del
# print(a)

# class File():
#     # 处理文件的
#     def __init__(self,file_path):
#         self.f = open(file_path)
#         self.name = 'alex'
#
#     def read(self):
#         self.f.read(1024)
#
#     def __del__(self):   # 是去归还/释放一些在创建对象的时候借用的一些资源
#         # del 对象的时候   程序员触发
#         # python解释器的垃圾回收机制 回收这个对象所占得内存的时候  python自动触发的
#         self.f.close()
# f = File('文件名')
# f.read()
# 不管是主动还是被动,这个f对象总会被清理掉,被清理掉就触发__del__方法,
触发这个方法就会归还操作系统的文件资源
示例

item 系列 和对象使用[]访问值有联系  __getitem__,__setitem__ ,__delitem__

在内置的模块中,
有一些特殊的方法,要求对象必须实现__getitem__/__setitem__才能使用

 

class A:
    def __getitem__(self, item):
        return getattr(self,item)
    def __setitem__(self, key, value):
        return setattr(self,key,value)
    def __delitem__(self, key):
        return delattr(self,key)
a=A()
a['key']=111  #触发的是__setitem__ 
print(a['key'])  #触发的是__getitem__
del a['key']    #触发的是__delitem__
print(a['key'])

# 用对象操作列表
class A:
    def __init__(self,lis):
        self.lis=lis
    def __getitem__(self, item):
        return self.lis[item]
    def __setitem__(self, key, value):
        self.lis[key]=value
    def __delitem__(self, key):
        self.lis.pop(key)
lis=[1,2,3,4,5,6,7]
a=A(lis)
a[1]='你好啊'
print(a.lis)
del a[2]
print(a.lis)
print(a[0])
示例

 __hash__

hash方法 

底层数据结构基于hash值寻址的优化操作

hash是一个算法

能够把某一个要存在内存的值通过一系列计算,保证不同的值的hash结构不一样

对同一个值在多次执行python代码的时候hash值是不同

但是对同一个值在同一次执行python代码的时候hash值永远不变

 

# print(hash('abc'))
# print(hash('abc'))
# print(hash('abc'))   一次执行的时候hash值不变

__eq__

 ==这个语法 是完全和__eq__相关

class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        if self.name == other.name and self.age == other.age:
            return True
a = A('alex',83)
aa = A('alex',83)
aa2 = A('alex',83)
aa3 = A('alex',83)
aa4 = A('alex',83)

print(aa3 == aa == aa4)
示例
# 一个类
# 对象的属性 : 姓名 性别 年龄 部门
# 员工管理系统
# 内部转岗 python开发 - go开发
# 姓名 性别 年龄 新的部门
# alex None 83 python
# alex None 85 luffy

# 1000个员工
# 如果几个员工对象的姓名和性别相同,这是一个人
# 请对这1000个员工做去重

class Employee:
    def __init__(self,name,age,sex,partment):
        self.name = name
        self.age = age
        self.sex = sex
        self.partment = partment
    def __hash__(self):
        return hash('%s%s'%(self.name,self.sex))
    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:
            return True
employ_lst = []
for i in range(200):
    employ_lst.append(Employee('alex',i,'male','python'))
for i in range(200):
    employ_lst.append(Employee('wusir',i,'male','python'))
for i in range(200):
    employ_lst.append(Employee('taibai', i, 'male', 'python'))

# print(employ_lst)
employ_set = set(employ_lst)
for person in employ_set:
    print(person.__dict__)

# set集合的去重机制 : 先调用hash,再调用eq,eq不是每次都触发,只有hash值相等的时候才会触发
一道经典题

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2018-07-31 09:45  玫瑰制造丶  阅读(51)  评论(0)    收藏  举报