面向对象2

# 面向对象

#类方法 静态方法 属性方法
普通的方法 类方法 静态方法 默认参数 self cls 无 操作的变量 操作对象的属性 操作静态属性 既不操作对象属性,也不操作类的属性 所属的命名空间 类 类 类 调用方式 对象 类
/对象 类/对象 对应的装饰器 无 @classmethod @staticmethod

@classmethod     (类方法 操作对象的属性 self默认参数  调用方法对象)
@property (方法伪装成属性一样使用,调用时候不加括号,也就没有参数)
@staticmethod (静态方法 既不操作对象属性,也不操作类的属性 无默认参数)
class A:
@classmethod 类方法
def c(cls):
print('cls')

@staticmethod 静态方法
def b():
print('B')

@property 方法变属性
def a(self):
print(1)
return 2

print(A().a)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象   返回布尔值
class Foo(object):
     pass
obj = Foo()
isinstance(obj, Foo)

issubclass(sub, super)检查sub类是否是 super 类的派生类  返回布尔值
class Foo(object):
    pass
class Bar(Foo):
    pass
print(issubclass(Bar, Foo))  #object/True
反射? 通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名)
getattr(命名空间,'key')  == 命名空间.key
所有的a.b都可以被反射成getattr(a,'b')
a.b
class Foo(object):
    def __init__(self):
        self.__func()    # _Foo__func
        # self.func()
    def __func(self):
        print('in Foo __func')  # _Foo__func
    def func(self):
        print('in Foo func')

class Son(Foo):
    def __func(self):
        print('in Son __func')   # _Son__func
    def func(self):
        print('in Son func')
s = Son()  #in Foo __func

# from sys import modules
# a = 2
# b = 4
# print(getattr(modules[__name__],'c',123))
# print(getattr(modules[__name__],'a'))
四个可以实现反射的函数:
下面方法适用于类和对象(一切皆为对象,类本身也是一个对象)
# hasattr() 检测存在不
# getattr() 获取
# setattr() 设置
# delattr() 删除
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'))  #True
print(hasattr(obj,'say_hi')) #True
#获取属性
print(getattr(obj,'name')) #egon
getattr(obj,'say_hi')() #hi,egon
print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
#设置属性
setattr(obj,'sb','value') #setattr(x, 'y', v) is equivalent to ``x.y = v''
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__) #{'name': 'egon', 'age': 73, 'sb': 'value', 'show_name': <function <lambda> at 0x0000000002985620>}
print(obj.show_name(obj)) #egonsb
#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错
print(obj.__dict__)
#类也是对象
class Foo(object):
    staticField = "old boy"
    def __init__(self):
        self.name = 'wupeiqi'

    def func(self):
        return 'func'

    @staticmethod
    def bar():
        return 'bar'

print(getattr(Foo, 'staticField'))
print(getattr(Foo, 'func'))
print(getattr(Foo, 'bar'))
import sys
def s1():
    print( 's1')

def s2():
    print ('s2')

this_module = sys.modules[__name__]

print(hasattr(this_module, 's1')) #True
print(getattr(this_module, 's2')) #<function s2 at 0x0000000002955620>
print(this_module)  #<module '__main__' from 'D:/复习/6_9.py'>
__str__和__repr__
改变对象的字符串显示__str__,__repr__
自定制格式化字符串__format__
'''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
format_dict={
    'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
    'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
    'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
    def __init__(self,name,addr,type):
        self.name=name
        self.addr=addr
        self.type=type

    def __repr__(self):
        return 'School(%s,%s)' %(self.name,self.addr)
    def __str__(self):
        return '(%s,%s)' %(self.name,self.addr)

    def __format__(self, format_spec):
        # if format_spec
        if not format_spec or format_spec not in format_dict:
            format_spec='nat'
        fmt=format_dict[format_spec]
        return fmt.format(obj=self)

s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1)) #from repr:  School(oldboy1,北京)
print('from str: ',str(s1)) #from str:  (oldboy1,北京)
print(s1) #(oldboy1,北京)

print(format(s1,'nat')) #oldboy1-北京-私立
print(format(s1,'tna')) #私立:oldboy1:北京
print(format(s1,'tan')) #私立/北京/oldboy1
print(format(s1,'asfdasdffd')) #oldboy1-北京-私立
%s 和 %r
class
B: def __str__(self): return 'str : class B' def __repr__(self): return 'repr : class B' b = B() print('%s' % b) #str : class B print('%r' % b) #repr : class B

item 系列

__getitem__\__setitem__\__delitem__

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

    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',12)
print(f1.__dict__)

f1['age']=18
f1['age1']=19
del f1.age1   #__delattr__
del f1['age']  #__delitem__
f1['name']='alex'
print(f1.name) #__getitem__
item

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

  析构函数的调用是由解释器在进行垃圾回收时自动触发执行的

class Foo:
    def __del__(self):
        print('执行我啦')
f1=Foo()
del f1
print('------->')
简单实现

__new__ 开辟空间 构造方法

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() #先执行__new__ 再执行__init__
print(a.x) # 1 对象.属性
实例化的过程
class Singleton:
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            cls._instance = object.__new__(cls)
        return cls._instance

one = Singleton()
two = Singleton()

two.a = 3
print(one.a) #3
# one和two完全相同,可以用id(), ==, is检测
print(id(one))
print(id(two))
print(one == two)# True
print(one is two)# True
单例模式

__call__ 对象后面加(),触发执行

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

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

obj = Foo()  # 执行 __init__
obj()  # 执行 __call__
代码示例

with 和 __enter__ ,__exit__  with 本质就是执行了enter和exit方法

__len__  长度

__hash__ 哈希

__eq__ 相同

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)
__eq__
class FranchDeck:
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    suits = ['红心','方板','梅花','黑桃']

    def __init__(self):
        self._cards = [(rank,suit) for rank in FranchDeck.ranks
                                        for suit in FranchDeck.suits]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, item):
        return self._cards[item]

deck = FranchDeck()
print(deck._cards)
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))
纸牌
class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def __hash__(self):
        return hash(self.name+self.sex)

    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:return True

p_lst = []
for i in range(84):
    p_lst.append(Person('egon',i,'male'))

print(p_lst)
print(set(p_lst)) #{<__main__.Person object at 0x0000000001F48080>}
一道面试题

 

字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名)
posted @ 2019-06-09 23:03  追风zz  阅读(118)  评论(0编辑  收藏  举报