Java教程

面向对象3

本文主要是介绍面向对象3,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

今日内容概要

  1. 反射实际案例
  2. 面向对象的双下方法
  3. 元类
  4. 元类进阶
  5. 设计模式之单列模式

面向对象3

反射实际案例
# 利用面向对象编写系统终端功能
我们以windows系统和Linus系统为列
class WinClub(object):  # 将系统作为类设计出来
    def ls(self):
        print('windows系统正在执行ls命令')
    def dir(self):
        print('windows系统正在执行dir命令')
    def cd(self):
        print('windows系统正在执行cd命令')
class LinusCmd(object):
    def Ls(self):
        print('Linux系统正在执行ls命令')
    def Dir(self):
        print('Linux系统正在执行dir命令')
    def Cd(self):
        print('Linux系统正在执行cd命令')
res = WinClub()  # 将系统
alex = LinusCmd()
我们在调用上方反射的数据的时候 已经帮我们返回出了数据和功能
def run(obj):
    while True:
        cmd = input('请输入您的指令')
        if hasattr(obj,cmd):
            func_name = getattr(obj,cmd)
            func_name()
        else:
            print('cmd command not found')

run(alex)

面向对象的双下方法

"""
面向对象中的双下方法也有一些人称之为是魔法方法
	有些双下方法不需要刻意调用 到达某个条件会自动触发
		__init__		对象实例化的时候自动触发
"""
1. __str__
	class MyClass(object):    # 定义名称空间
    def __init__(self, name):  #  双下init给name赋值
        self.name = name  #  给名称空间里的name赋值实例化对象
 	对象被执行打印(print、前端展示)操作的时候自动触发
     该方法必须返回字符串类型的数据
  很多时候用来更加精准的描述对象
        return '对象:%s'%self.name  # 这个返回值才是我们能调用的
2.	__del__     
	def __del__(self):
         """对象被执行(被动、主动)删除操作之后自动执行"""
        print("del啥时候执行")
        pass
对象被执行(被动、主动)删除操作之后自动执行
3. __getattr__
  对象查找不存在名字的时候自动触发
    def __getattr__(self, item):
        """对象查找不存在名字的时候自动触发"""
        print('__getattr__方法', item)
        return '不好意思 没有%s这个名字'%item
4. __setattr__
	对象在执行添加属性操作的时候自动触发	>>>	obj.变量名=变量值
    class MyClass(object):
    def __init__(self,name):
        self.name = name
    def __setattr__(self, key, value):
        if not value.isupper():
            raise Exception('只支持大写输出')
        super().__setattr__(key,value)
res = MyClass('JAMES')
print(res.__dict__)
5.__call__
	对象被加括号调用的时候自动触发
    def __call__(self, *args, **kwargs):
        """对象被加括号调用的时候自动触发"""
    print('__call__方法',args,kwargs)
    return '嘿嘿嘿'
6.__enter__
	对象被执行with上下文管理语法开始自动触发 
  	该方法返回什么as后面的变量名就会得到什么
7.__exit__
	对象被执行with上下文管理语法结束之后自动触发
8.__getattribute__:只要对象查找名字,无论名字是否存在都会执行该方法,如果类中有__getattribute__方法就不会
执行__getattr__方法。
class Student:
    def __init__(self,name):
        self.name = name
    def __getattribute__(self, item):
        print('无论什么时候打印我')
        return item
 
obj = Student('oscar')
print(obj.name)  # 都会执行打印,不会报错
print(obj.age)  # 都会执行打印,不会报错

笔试题讲解

class MyClass(dict):
    def __init__(self,name):
        self.name = name
    def __getattr__(self, item):
        return self.get(item)
    def __setattr__(self, key, value):
        self[key] = value
        super().__setattr__(key,value)
res = MyClass({'name':'jack'})
print(res.name)
print(res.age)  # 没有的键值的情况下 不会报错 返回一个 None
print(res.__dict__) #这里调用的是res的名称空间 是一个空字典  {}
# 调用后{'name': {'name': 'jack'}}
'''解决方法 调用__init__方法实列化'''
2.补全下列代码 使其运行不报错
	"""
	class Context:
			pass
	with Context() as ctx:
			ctx.do_something()
	"""
  class Context:
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass
    def do_something(self):
        pass
	with Context() as ctx:
    ctx.do_something()

元类简介

1.元类即原始的类,产生类的类。
2.学习元类的目的:元类能够控制类的创建,也就意味着我们可以高度定制类的行为。
# print(type(123))
# print(type([12, 33, 44]))
# print(type({'name':'jason','pwd':123}))
# type查看的其实是当前对象所属的类名称
class MyClass(object):
    pass
obj = MyClass()
print(type(obj))
print(type(MyClass))  # <class 'type'>

class Student:
    pass
print(type(Student))  # <class 'type'>

class Teacher(MyClass):
    pass
print(type(Teacher))  # <class 'type'>
'''type就是所有类默认的元类!!!'''
产生类的两种表现形式(本质是一种)
方式1:
1.class关键字
    	class 类名:
    		类体代码
2. type元类 
	# type(类名,父类,类的名称空间)
	res = type('Student',(),{})
	print(res)  # <class 		'__main__.Student'>

元类的基本使用
"""元类是不能通过继承的方式直接指定的"""
	需要通过关键字参数的形式修改
  	class C1(metaclass=MyTypeClass):
    	pass
    
class MyTypeClass(type):
    def __init__(cls, cls_name, cls_bases, cls_dict):
        # print(cls, cls_name, cls_bases, cls_dict)
        if not cls_name.istitle():
            raise Exception("类名的首字母必须大写 你个SD")
        super().__init__(cls_name, cls_bases, cls_dict)

class C1(metaclass=MyTypeClass):
    school = '清华大学'

class a(metaclass=MyTypeClass):
    school = '清华大学'

元类进阶操作

1.我们之前讲__call__方法的时候,对象加括号会自动执行产生该对象的类里面的__call__,并且该方法返回什么对象加
括号就会得到什么,那我们就可以推导类加括号会执行元类的里面的__call__,该方法返回什么类加括号就会得到什么。
2.类里面的__init__和元类的__call__执行的先后顺序。
class Student(type):
    def __call__(self, *args, **kwargs):
        print('我是__call__')
        super().__call__(*args, **kwargs)


class Teacher(metaclass=Student):
    def __init__(self, name):
        print('我是__init__')
        self.name = name


obj = Teacher('oscar')
# 定制对象的产生过程
	class MyTypeClass(type):
    def __call__(self, *args, **kwargs):
        # print('__call__ run')
        # print(args,kwargs)
        if args:
            raise Exception('必须全部采用关键字参数')
        super().__call__(*args, **kwargs)

  class MyClass(metaclass=MyTypeClass):
      def __init__(self, name):
          # print('__init__ run')
          self.name = name

	"""强制规定:类在实例化产生对象的时候 对象的独有数据必须采用关键字参数"""
  # obj1 = MyClass('jason')
  obj2 = MyClass(name='jason')
"""
如果你想高度定制类的产生过程
	那么编写元类里面的__init__方法
如果你想高度定制对象的产生过程
	那么编写元类里面的__call__方法
"""

双下new方法

__new__用于产生空对象(类)	一个空的名称空间
__init__用于实例化对象(类)	 将产生的数据实例到名称空间
	# 并不是所有的地方都可以直接调用__new__,该方法过于底层。
1.如果是在元类的__new__里面可以直接调用
class Student(type):
    def __call__(cls, *args, **kwargs):
        obj = type.__new__(cls,*args,**kwargs)
        return obj
2.如果在元类的__call__里面需要间接调用
class Student(type):
    def __call__(self, *args, **kwargs):
        obj = type.__new__(self)  # 创建一个空对象
        self.__init__(obj,*args,**kwargs)  # 让对象去初始化
        return obj
这篇关于面向对象3的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!