码迷,mamicode.com
首页 > 编程语言 > 详细

python进阶(7):面向对象进阶

时间:2017-08-16 20:31:43      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:att   技术   size   技术分享   one   name   定义   demo1   sel   

学了面向对象三大特性继承,多态,封装。今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数。

 

一、isinstance和issubclass

class Foo:
    pass

class Son(Foo):
    pass

s = Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
print(isinstance(s,Son))
print(isinstance(s,Foo))
#type更精准
print(type(s) is Son)
print(type(s) is Foo)

#判断一个类是不是另一类的子类,传两个参数(子类,父类)
print(issubclass(Son,Foo))
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))

 

二、反射

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

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

四个可以实现反射的函数:hasattr,getattr,setattr,delattr

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

技术分享
class Foo:
    def __init__(self):
        self.name = egon
        self.age = 73

    def func(self):
        print(123)

egg = Foo()
#常用:
#hasattr
#getattr
# print(hasattr(egg,‘name‘))
print(getattr(egg,name))
if hasattr(egg,func):   #返回bool
    Foo_func = getattr(egg,func)  #如果存在这个方法或者属性,就返回属性值或者方法的内存地址
                                 #如果不存在,报错,因此要配合hasattr使用
    Foo_func()
#不常用:
#setattr
# setattr(egg,‘sex‘,‘属性值‘)
# print(egg.sex)
# def show_name(self):
#     print(self.name + ‘ sb‘)
# setattr(egg,‘sh_name‘,show_name)
# egg.sh_name(egg)
# show_name(egg)
# egg.sh_name()

#delattr
# delattr(egg,‘name‘)
# print(egg.name)


# print(egg.name)
# egg.func()
# print(egg.__dict__)


#反射
#可以用字符串的方式去访问对象的属性、调用对象的方法
反射举例1
技术分享
class Foo:
    f = 123 #类变量
    @classmethod
    def class_method_demo(cls):
        print(class_method_demo)
    @staticmethod
    def static_method_demo():
        print(static_method_demo)
# if hasattr(Foo,‘f‘):
#     print(getattr(Foo,‘f‘))
print(hasattr(Foo,class_method_demo))
method = getattr(Foo,class_method_demo)
method()
print(hasattr(Foo,static_method_demo))
method2 = getattr(Foo,static_method_demo)
method2()
#类也是对象
反射举例2
技术分享
import my_module
# print(hasattr(my_module,‘test‘))
# # func_test = getattr(my_module,‘test‘)
# # func_test()
# getattr(my_module,‘test‘)()
#import其他模块应用反射

from my_module import test


def demo1():
    print(demo1)

import sys
print(__name__)  #‘__main__‘
print(sys.modules)
#‘__main__‘: <module ‘__main__‘ from ‘D:/Python代码文件存放目录/S6/day26/6反射3.py‘>
module_obj =sys.modules[__name__]  #sys.modules[‘__main__‘]
# module_obj : <module ‘__main__‘ from ‘D:/Python代码文件存放目录/S6/day26/6反射3.py‘>
print(module_obj)
print(hasattr(module_obj,demo1))
getattr(module_obj,demo1)()
#在本模块中应用反射
反射举例3
技术分享
#对象
#
#模块 : 本模块和导入的模块

def register():
    print(register)

def login():
    pass

def show_shoppinglst():
    pass
#
print(注册,登录)
ret = input(欢迎,请输入您要做的操作: )
import sys
print(sys.modules)
# my_module = sys.modules[__name__]
# if hasattr(my_module,ret):
#     getattr(my_module,ret)()
if ret == 注册:
    register()
elif ret == 登录:
    login()
elif ret == shopping:
    show_shoppinglst()
反射举例4
技术分享
def test():
    print(test)
my_module(第三个例子用到的模块)

 

三、类的内置函数

1、__str__和__repr__

class Foo:
    def __init__(self,name):
        self.name = name
    def __str__(self):
        return %s obj info in str%self.name
    def __repr__(self):
        return obj info in repr

f = Foo(egon)
# print(f)
print(%s%f)
print(%r%f)
print(repr(f))  # f.__repr__()
print(str(f))
#当打印一个对象的时候,如果实现了str,打印中的返回值
#当str没有被实现的时候,就会调用repr方法
#但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
#不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
#但反之不行
#用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr

2、__del__

class Foo:
    def __del__(self):
        print(执行我啦)

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

3、item系列

__getitem__\__setitem__\__delitem__

class Foo:
    def __init__(self):
        self.name = egon
        self.age = 73
        
    def __getitem__(self, item):
        return self.__dict__[item]

    def __setitem__(self, key, value):
        # print(key,value)
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]
f = Foo()
print(f[name])
print(f[age])
f[name] = alex
# del f[‘name‘]
print(f.name)
f1 = Foo()
print(f == f1)

4、__new__

# class A:
#     def __init__(self):  #有一个方法在帮你创造self
#         print(‘in init function‘)
#         self.x = 1
#
#     def __new__(cls, *args, **kwargs):
#         print(‘in new function‘)
#         return object.__new__(A, *args, **kwargs)
# a = A()
# b = A()
# c = A()
# d = A()
# print(a,b,c,d)

#单例模式
class Singleton:
    def __new__(cls, *args, **kw):
        if not hasattr(cls, _instance):
            cls._instance = object.__new__(cls, *args, **kw)
        return cls._instance

one = Singleton()
two = Singleton()
three = Singleton()
go = Singleton()
print(one,two)

one.name = alex
print(two.name)

5、__call__

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

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

6、__len__,__hash__

class Foo:
    def __len__(self):
        return len(self.__dict__)
    def __hash__(self):
        print(my hash func)
        return hash(self.name)
f = Foo()
print(len(f))
f.name = egon
print(len(f))
print(hash(f))

7、__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__控制着==的结果

 

8、内置函数实例 

技术分享
class FranchDeck:
    ranks = [str(n) for n in range(2,11)] + list(JQKA)
    suits = [红心,方板,梅花,黑桃]

    def __init__(self):
        self._cards = [Card(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[0])
from random import choice
print(choice(deck))
print(choice(deck))
纸牌游戏
技术分享
class FranchDeck:
    ranks = [str(n) for n in range(2,11)] + list(JQKA)
    suits = [红心,方板,梅花,黑桃]

    def __init__(self):
        self._cards = [Card(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]

    def __setitem__(self, key, value):
        self._cards[key] = value

deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))

from random import shuffle
shuffle(deck)
print(deck[:5])
纸牌游戏2
技术分享
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 other.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))

#只要姓名和年龄相同就默认为一人去重
去重

 

python进阶(7):面向对象进阶

标签:att   技术   size   技术分享   one   name   定义   demo1   sel   

原文地址:http://www.cnblogs.com/liluning/p/7374971.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!