谈谈你对面向对象的认识?
基础:面向对象的三大特性:封装,继承,多态
封装:
方法封装到类中
class File:
def file_add():pass
def file_update():pass
def file_del():pass
def file_fetch():pass
数据封装到对象中:
class File:
def __init__(self,name,age,email):
self.name = name
self.age = age
self.email = email
def file_add():pass
def file_update():pass
def file_del():pass
def file_fetch():pass
obj1 = File('oldboy',19,"asdf@live.com")
obj2 = File('oldboy1',119,"asdf12@live.com")
应用:
- session/request封装到来RequestContext对象中
- app/g封装到了AppContext中
继承:如果多个类中有相同的方法,为了避免重复编写,可以将其放在父类(基类)中。
class Base(object):
def xxxx():pass
class File(Base):
def __init__(self,name,age,email):
self.name = name
self.age = age
self.email = email
def file_add():pass
def file_update():pass
class DB(Base):
def db_add():pass
def db_update():pass
应用:
rest framework中的视图类的继承
多态(鸭子模型):天生支持多态,对于参数来说可以传入任何类型的对象,只要保证有想要的send方法即可。
class Msg(object):
def send():
pass
class WX(object):
def send():
pass
def func(arg):
arg.send()
- 进阶:
__init__,初始化
__new__,创建对象
__call__,对象()
__getattr__,对象.xx
__setattr__
__delattr__
__setitem__,对象['xx']
__getitem__
__delitem__
__mro__,查找成员顺序
__str__
__repr__
__iter__
__dict__
__add__
高级:metaclass
1. 类创建
class Foo(object):pass
Foo = type('Foo',(object,),{})
2. 如何指定类由自定义type创建?
class MyType(type):
pass
class Foo(object,metaclass=MyType):
# __metaclass__ = MyType # py2
pass
Foo = MyType('Foo',(object,),{})
3. 默认执行顺序
class Foo(object,metaclass=MyType):
pass
obj = Foo()
class MyType(type):
def __init__(self,*args,**kwargs):
print('111')
super(MyType,self).__init__(*args,**kwargs)
class Base(object, metaclass=MyType):
pass
class Foo(Base):
pass
如果一类自己或基类中指定了metaclass,那么该类就是由metaclass指定的type或mytype创建。
同:
class MyType(type):
def __init__(self,*args,**kwargs):
print('111')
super(MyType,self).__init__(*args,**kwargs)
# class Base(object, metaclass=MyType):
# pass
Base = MyType('Base',(object,),{})
class Foo(Base):
pass
同:
class MyType(type):
def __init__(self,*args,**kwargs):
print('111')
super(MyType,self).__init__(*args,**kwargs)
# class Base(object, metaclass=MyType):
# pass
def with_metaclass(arg):
Base = MyType('Base',(arg,),{})
return Base
class Foo(with_metaclass(object)):
pas
4. 了解:
- 视图,虚拟表。
- 触发器,在对某张表进行:增、删、改的前后自定义操作。
- 函数,对数据中的值进行操作。
select sleep(10);
select max(id) from xx;
select date_format('ctime','%s....') from tb;
select id,SUBSTRING(name,1,1) from users;
自定义函数:
delimiter \\-
create function f1(
i1 int,
i2 int)
returns int
BEGIN
declare num int;
set num = i1 + i2;
return(num);
END \\
delimiter ;
- 存储过程,对结果集合返回值进行复杂操作。
delimiter //
create procedure p2(
in n1 int,
out n2 int,
)
begin
declare temp1 int ;
declare temp2 int default 0;
insert into tb(title) values();
insert into tb(title) values();
insert into tb(title) values();
set n2 = 1;
end //
delimiter ;
5. 索引
种类:
- 主键
- 唯一
- 普通
- 联合
- 联合唯一
ps: 最左前缀
名词:
- 覆盖索引
- 索引合并。
。
6. 创建索引,但无法命中索引。
https://www.cnblogs.com/wupeiqi/articles/5716963.html
select * from tb1 where name='alex';
- like '%xx'
select * from tb1 where name like '%cn';
- 使用函数
select * from tb1 where reverse(name) = 'wupeiqi';
- or
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当or条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
- 类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
- !=
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
- >
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
- order by
select email from tb1 order by name desc;
当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc;
- 组合索引最左前缀
如果组合索引为:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引