zoukankan      html  css  js  c++  java
  • python之路_面向对象相关知识点

    1、方法与函数的区别?

    '''
    class Foo(object):
        def __init__(self):
            self.name = 'alex'
        def func(self):
            print(self.name)
    from types import FunctionType,MethodType
    
    obj = Foo()
    print(isinstance(obj.func,FunctionType))             # False
    print(isinstance(obj.func,MethodType))               # True
    
    print(isinstance(Foo.func,FunctionType))             # True
    print(isinstance(Foo.func,MethodType))               # False
    注意:
        方法,无需传入self参数;函数,必须手动传入self参数
    '''

    2、models对象相关查询

    '''
    例:model.UserInfo为models类
    '''
        #(1)获取models类所在app名:model.UserInfo._meta.app_label
        #(2)获取models类的类名小写:model.UserInfo._meta.model_name
        #(3)获取models类中的字段内容:model.UserInfo._meta.get_field('username')
        #(4)获models类中字段的verbose_name:model.UserInfo._meta.get_field('username').verbose_name

    3、用type创建类的实现

    '''type创建TestModelForm类,参数分别为类名,继承类,类中属性'''

    meta = type('Meta',(object,),{'model':self.model_class,'fields':'__all__'}) TestModelForm = type('TestModelForm',(ModelForm,),{'Meta':meta}) #等价于 class TestModelForm(ModelForm): class Meta: model = self.model_class fields = "__all__"

    4、反向生成url

    #示例如下:namespace为名称空间,name为url别名

    reverse("namespace:name")

     5、instance与type区别

      有这样一个错误说法:isinstance用于判断,对象是否是指定类的实例,具体情况见下实例:

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    obj = Bar()
    
    print(isinstance(obj,Foo))      #True
    print(isinstance(obj,Bar))       #True

      所以结论是:isinstance用于判断对象是否是指定类或其派生类的实例,如果需要排除派生类的情况,我们就不能用instance进行实例判断,为了实现这种,就需要使用type进行判断了。示例如下:

    print(type(obj) == Bar)     #True
    
    print(type(obj) == Foo)     #False

    6、面向对象中的反射相关

      在django中,配置文件中中间件的配置方式如下,其实配置的就是不同中间模块的路径。我们可能好奇,这样的字符串形式的配置,内部是如何读取到相应模块中的内容的呢?

    通过源码我们发现,其主要也是通过反射实现的,见如下实例:

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    有这样一个setting.py文件,配置了某类的路径:

    DB_PATH = "db.sqlserver.SqlServerHelper"

    获得SqlServerHelper类,并执行其中相关方法:

    from settings import DB_PATH
    
    def func():
        # DB_PATH = "db.mysql.MySQLHelper"
        module_path,cls_name = DB_PATH.rsplit('.',maxsplit=1)
    
        # 以字符串的形式导入模块
        import importlib
        module_obj = importlib.import_module(module_path)
    
        # 去模块中导入类
        cls = getattr(module_obj,cls_name)
    
        # 类实例化
        obj = cls()
        obj.fetchone()
    
    
    if __name__ == '__main__':
        func()

    还有这样一个实例:根据方法名,去实例对象中获得该方法。

    class Foo(object):
        def func(self):
            pass
    
    obj = Foo()
    name = "func"
    fc = getattr(obj,name)
    
    fc()

    7、面向对象封装数据相关

      有这样一个应用,我们需要将models对象中相应的部分字段信息传给后端,我们相当的数据类型可能是:[{},{},{}.....],其中字典中为每个字段的相应信息。这样做没有问题,但是当我们需要的数据不但不含字段的直接信息,还要包含根据字段获得其他间接数据。这样的话,上述方式就比较难做到。此时我们就可以借助面向对象的封装特性,将数据封装到类中,间接数据的获得可以在类中的方法实现,最终只需将实例化的类对象发给后端就可以。具体实例如下:

    #封装数据的类
    class FilterOption(object):
        def __init__(self,field_name,multi=False,condition=None,is_choice=False):
            """
            
            :param field_name: 字段
            :param multi:  是否多选
            :param condition: 显示数据的筛选条件
            :param is_choice: 是否是choice
            """
            self.field_name = field_name
            self.multi = multi
            self.is_choice = is_choice
    
            self.condition = condition
    
        def get_queryset(self,_field):
            if self.condition:
                return _field.rel.to.objects.filter(**self.condition)     
            return _field.rel.to.objects.all()
    
        def get_choices(self,_field):
            return _field.choices
    

    #发送的数据形式: comb_filter = [ FilterOption('gender',is_choice=True), FilterOption('depart',condition={'id__gt':3}), FilterOption('roles',True), ]

      如上,通过循环列表,通过实例对象就可以获得封装到类中的所有数据。

    8、两个对象相加(__add__)

    class Foo(object):
    
        def __init__(self,age):
            self.age = age
    
        def __add__(self, other):
            return self.age + other.age
            # return Foo(self.age + other.age)
    
    obj1 = Foo(19)
    obj2 = Foo(18)
    
    obj3 = obj1 + obj2
    print(obj3)

     9、类中的方法约束

      有这样的情况,我们需要规定多个类中,每一个类中都要一个相同的方法。如何实现这样的约束呢?有两种方式,如下。说明:如下实例要求所有写的类中必须要有send方法,如果没有该方法时,实例化对象调用该方法时会报错。

    方式一:抽象类、抽象方法实现

      如下实例,我们定义了一个基类BaseMessage,继承抽象类,通过使用@abstractmethod装饰方法send,send方法成为抽象方法,所有继承BaseMessage基类的类中必须要有send方法,否则执行此类时会报错。

    from abc import ABCMeta
    from abc import abstractmethod
    class BaseMessage(metaclass=ABCMeta):
        @abstractmethod
        def send(self,subject,body,to,name):
            pass
    ######################################3
    class WeChat(BaseMessage):
        def __init__(self):
            pass
            print("xxx")
    
        def send(self,subject,body,to,name):
            print('微信发送成功')

    方法二:自定义基类方式实现

      如下,自定义基类BaseMessage,在基类中定义一个send方法,方法内抛出没有该方法的异常NotImplementedError。WeChat类继承基类,实例化后调用send方法时,如果此类中没有定义该方法,则会去基类中找。从而会抛出异常。

    class BaseMessage(object):
        def send(self, subject, body, to, name):
            raise NotImplementedError('未实现send方法')
    
    class WeChat(BaseMessage):
        def __init__(self):
            pass
            print("xxx")
    
        def send(self,subject,body,to,name):
            print('微信发送成功')

      总结,以上两种方法均在基类中进行特定方法限制,所有继承此基类的类中必须要有此方法。不同的是,方法一中要求所有继承基类的类中必须有抽象方法规定的方法,否则类在实例化的时候就会报错。但是方法二中不同的是,若自定义的类中没有实现send方法时候,在类的实例化过程中不会报错,实例对象可以正常调用类中有的方法和属性,只有实例对象在调用send方法时候会报错。

  • 相关阅读:
    C#:正则表达式
    jsp:
    关于博客的设置
    登录注册案例—MongoDB数据库连接
    cookie封装
    博客样式
    自己的博客
    CentOS7 启动docker.service失败
    合并多个jar包,并通过私服依赖
    springboot+支付宝条码支付开发详解
  • 原文地址:https://www.cnblogs.com/seven-007/p/8511772.html
Copyright © 2011-2022 走看看