方法和函数区分
fun及Foo.display为函数,obj.display为方法,类实例化后,之前的函数就变成了方法
def fun():
pass
print(fun)
class Foo(object):
def display(self):
pass
print(Foo.display)
obj = Foo()
print(obj.display)
<function fun at 0x0000028F1303D268>
<function Foo.display at 0x0000028F160B48C8>
<bound method Foo.display of <__main__.Foo object at 0x0000028F133ABAC8>>
写一个函数来区分对象
from types import MethodType,FunctionType
def check(args):
if isinstance(args,MethodType):
print('这是方法')
elif isinstance(args,FunctionType):
print('这是函数')
else:
print('这是啥')
check(fun)
check(obj.display)
这是函数
这是方法
小练习
class RoleConfig(object):
def f1(self,args):
print('f1',args)
def f2(self,args):
print('f2',args)
def f3(self,args):
print('f3',args)
list_display = [f1,f2]
def get_list_display(self):
self.list_display.insert(0,obj.f3)
return self.list_display
obj = RoleConfig()
for item in obj.get_list_display():
item(obj,2)
报错是因为obj中此时的f3为方法,而f1、f2为函数
Traceback (most recent call last):
File "D:/Practise/project01/app02/test/20220110.py", line 21, in <module>
item(obj,2)
TypeError: f3() takes 2 positional arguments but 3 were given
单例模式
编辑三个模块
test1
class AdminSite(object):
pass
obj1 = AdminSite()
test2
import test1
print(test1.obj1)
import test3
test3
import test1
print(test1.obj1)
执行test2,显示内存地址相同,程序没有重复执行,是直接调用
<test1.AdminSite object at 0x000002CD41700FD0>
<test1.AdminSite object at 0x000002CD41700FD0>
想要使用单例模式,就像test1那样,直接在模块中实例化,其他模块使用时直接调用即可。
静态方法(类变量)
class RoleConfig(object):
def f1(self,args):
print('f1',args)
def f2(self,args):
print('f2',args)
def f3(self,args):
print('f3',args)
list_display = [f1,f2]
def get_list_display(self):
self.list_display.insert(0,RoleConfig.f3)
return self.list_display
obj = RoleConfig()
for item in obj.get_list_display():
item(obj,2)
obj1 = RoleConfig()
for item in obj1.get_list_display():
item(obj1,2)
打印结果为7行数据,第一次执行get_list_display(),list_display列表更新为[f1,f2,f3]
f3 2
f1 2
f2 2
f3 2
f3 2
f1 2
f2 2
解决办法
class RoleConfig(object):
def f1(self,args):
print('f1',args)
def f2(self,args):
print('f2',args)
def f3(self,args):
print('f3',args)
list_display = [f1,f2]
def get_list_display(self):
v = []
v.extend(self.list_display) #不要用v=list_display,否则效果跟之前一样
v.insert(0,RoleConfig.f3)
return v
obj = RoleConfig()
for item in obj.get_list_display():
item(obj,2)
obj1 = RoleConfig()
for item in obj1.get_list_display():
item(obj1,6)
这次就是六个结果了
f3 2
f1 2
f2 2
f3 6
f1 6
f2 6
Python三大器
生成器
迭代器
通过yield可以降低内存消耗
def func(request):
result = []
data_list = models.Users.objects.all()
for row in data_list:
temp = "%s%s" (row.name,row.pwd,)
result.append(temp)
return render(request,'xxx.html',{'result':result})
通过yield优化
def get_result(data_list):
for row in data_list:
temp = "%s%s" (row.name,row.pwd)
yield temp
def func(request):
data_list = models.Users.objects.all()
return = get_result(data_list)
return render(request,'xxx.html',{'result':result})
xxx.html
{% for row in result %}
{{row}}
{% endfor %}
可迭代对象
class Row(object):
def __init__(self,data):
self.data = data
def __iter__(self):
yield "<div>"
yield '全部'
for item in self.data:
yield "<a href='/index/?p1=1.0'>%s</a>" %item
yield "</div>"
data_list = [
Row(['1.0以下','1.1-1.6']),
Row(['汽油','柴油','混合动力','电动']),
]
for row in data_list:
for field in row:
print(field)
封装
##################################老封装思想,后期没有修改变更可以使用
list_filter = [
{'text':'董方方','gender':'男','color':'xx'},
{'text':'黄晓雪','gender':'男','color':'xx'},
{'text':'李贝贝','gender':'男','color':'xx'},
]
for item in list_filter:
print(item['text']+item['gender'])
###################################新封装思想,后期如果还有变化,可以使用这个方法,两种方式按需采用
class Option(object):
def __init__(self,text,gender,color):
self.text = text
self.gender = gender
self.color = color
def get_t_g(self):
return self.text+self.gender
list_filter = [
Option(text='董方方',gender='男',color='xx'),
Option(text='黄晓雪',gender='男',color='xx'),
Option(text='李贝贝',gender='男',color='xx'),
]
for item in list_filter:
print(item.get_t_g())
装饰器
functools
def wrapper(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@wrapper
def f1():
print('f1')
@wrapper
def f2():
print('f2')
print(f1.__name__)
print(f2.__name__)
结果
inner
inner
有functools
import functools
def wrapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@wrapper
def f1():
print('f1')
@wrapper
def f2():
print('f2')
print(f1.__name__)
print(f2.__name__)
结果
f1
f2
闭包
闭包
def f1(a1,a2):
def inner():
ret = a1 + a2
return ret
return inner
n1 = f1('test','test1') #内存 a1='test',a2='test1'
n2 = f1('test1','test2') #内存 a1='test1',a2='test2'
n3 = f1('test3','test4') #内存 a1='test3',a2='test4'
n1()
# 帮助开发作者维护一个"私密"空间,用于为以后执行提供数据。
反射
getattr
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def test(request):
from app01 import models
header_list = []
list_display=['id','username','phone']
for name in list_display:
header_list.append(models.UserInfo._meta.get_field(name).verbose_name)
print(header_list)
user_queryset = models.UserInfo.objects.all()
for item in user_queryset:
row = []
for field in list_display:
v = getattr(item,field)
row.append(v)
print(row)
return HttpResponse('test')
结果
['ID', '姓名', '手机号']
[1, 'name1', 1234]
[2, 'name2', 1234]
[3, 'name3', 1234]
常用
isinstance
判断对象是否为函数
from types import FunctionType
if isinstance(name_or_func,FunctionType):
val = name_or_func(self,item,False)
else:
val = getattr(item, name_or_func)
row.append(val)
Django
mark_safe
返回html到页面
from django.utils.safestring import mark_safe
from .models import Role,Dpet
class RoleConfig(StarkConfig):
def f1(self,row=None,header=False):
if header:
return '选择'
return mark_safe('<input type="checkbox" name="pk" value="%s" />' %row.pk)
list_display = [f1, 'id', 'title']
reverse
from django.urls import reverse
def display_edit(self, row=None, header=False):
if header:
return '编辑'
app_label = self.model_class._meta.app_label
model_name = self.model_class._meta.model_name
namespace = self.site.namespace
name = '%s:%s_%s_change'%(namespace,app_label,model_name)
url = reverse(name,kwargs={'pk':row.pk})
return mark_safe('<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a>'%url)
ModelForm
def add_view(self, request):
'''
所有添加页面,都在此函数处理
使用ModelForm实现
:param request:
:return:
'''
class AddModelForm(forms.ModelForm):
class Meta:
model = self.model_class
fields = "__all__"
if request.method == "GET":
form = AddModelForm()
return render(request, 'stark/change.html', {'form': form})
form = AddModelForm(request.POST)
if form.is_valid():
form.save()
redirect(self.reverse_list_url())
return render(request, 'stark/change.html', {'form': form})
<h1>添加页面</h1>
<div style="width: 680px;margin:0 auto">
<form class="change" method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
{{ field.errors.0 }}
</div>
{% endfor %}
<button type="submit" class="btn btn-default">提交</button>
</form>
</div>
获取FK/M2M/O2O对应的表中所有的数据
class UserInfo(models.Model):
title = models.CharField(verbose_name='标题',max_length=32)
def __str__(self):
return self.title
class Depart(models.Model):
name = models.CharField(verbose_name='部门名称',max_length=32)
tel = models.CharField(verbose_name='联系电话',max_length=32)
user = models.ForeignKey(verbose_name='负责人',to='UserInfo',on_delete=models.CASCADE)
def __str__(self):
return self.name
######fk_obj.rel.model.objects.all()中rel已不能使用,修改为remote_field
def get_fk_queryset(request):
from app02 import models
fk_obj = models.Depart._meta.get_field("user")
user_info_queryset = fk_obj.remote_field.model.objects.all()
print(user_info_queryset)
return HttpResponse('...')
Q对象
models.User.object.filter(name__containsj='李')
models.User.object.filter(name__contains='李',email__contains='李')
构造 or
con = Q()
con.children.append(('name__contains','李'))
con.children.append(('email__contains','李'))
models.User.object.filter(name__contains='李',email__contains='李')
c1 = Q()
c1.connector = 'OR'
c1.children.append(('name__contains','李'))
c1.children.append(('email__contains','李'))
c2 = Q()
c2.connector = 'AND'
c2.children.append(('id__gt',2))
c2.children.append(('age__lte',5))
c3 = Q()
c2.connector = 'AND'
c3.add(c1,'AND')
c3.add(c2,'AND')
(name=li or email=li) AND (id>2 and age<=5)
models.User.object.filter(con)
get_字段_display()
gender_choices = ((1, '男'), (2, '女'))
gender = models.IntegerField(verbose_name='性别', choices=gender_choices)
获取性别的名称而不是序号
get_gender_display()