python之路_面向对象相关知识点

一、方法与函数的区别?mysql

'''
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参数
'''

二、models对象相关查询sql

'''
例: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

三、用type建立类的实现django

'''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__"

四、反向生成url后端

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

reverse("namespace:name")

 五、instance与type区别微信

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

class Foo(object):
    pass

class Bar(Foo):
    pass

obj = Bar()

print(isinstance(obj,Foo))      #True
print(isinstance(obj,Bar))       #True

  因此结论是:isinstance用于判断对象是不是指定类或其派生类的实例,若是须要排除派生类的状况,咱们就不能用instance进行实例判断,为了实现这种,就须要使用type进行判断了。示例以下:app

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

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

六、面向对象中的反射相关函数

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

经过源码咱们发现,其主要也是经过反射实现的,见以下实例:fetch

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()

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

  有这样一个应用,咱们须要将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), ]

  如上,经过循环列表,经过实例对象就能够得到封装到类中的全部数据。

八、两个对象相加(__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)

 九、类中的方法约束

  有这样的状况,咱们须要规定多个类中,每个类中都要一个相同的方法。如何实现这样的约束呢?有两种方式,以下。说明:以下实例要求全部写的类中必需要有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方法时候会报错。

相关文章
相关标签/搜索