欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django利用Channels+websocket開發(fā)聊天室完整案例

 更新時(shí)間:2023年06月25日 10:29:07   作者:Aiwin-Hacker  
Channels是Django團(tuán)隊(duì)研發(fā)的一個(gè)給Django提供websocket支持的框架,使用它我們可以輕松開發(fā)需要長(zhǎng)鏈接的實(shí)時(shí)通訊應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于Django利用Channels+websocket開發(fā)聊天室的相關(guān)資料,需要的朋友可以參考下

前言

數(shù)據(jù)庫(kù)系統(tǒng)課程設(shè)計(jì)要求,要開發(fā)一個(gè)B2B的售賣平臺(tái),本來(lái)開發(fā)淺薄的我,粗糙又基礎(chǔ)的完成了一些基本的功能,想要開發(fā)一個(gè)單獨(dú)的一對(duì)一聊天的功能(類似于微信這類),查閱了不少資料,依舊沒思路,但是卻知曉了服務(wù)器推送信息和聊天室的開發(fā),記個(gè)筆記。

提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、什么是Websocket?

1,Websocket的誕生背景:網(wǎng)站為了實(shí)現(xiàn)推送技術(shù),用的基本是輪詢,輪詢是基于瀏覽器不斷對(duì)服務(wù)器發(fā)出HTTP請(qǐng)求,服務(wù)器范圍最新數(shù)據(jù)給客戶端瀏覽器,這種模式缺點(diǎn)明顯,帶寬浪費(fèi)嚴(yán)重,在這種背景下,HTML5誕生了Websocket協(xié)議,能更好的節(jié)省服務(wù)器資源并實(shí)現(xiàn)通訊。

2,WebSocket特點(diǎn):WebSocket是單個(gè)TCP連接上的全雙工通信,瀏覽器和服務(wù)器只需要完成一次握手,就可以創(chuàng)建持久性的連接,實(shí)現(xiàn)數(shù)據(jù)的雙向傳輸。

二、Python-Django ASGI

1,WSGI:Python Web Server Gateway Interface,就是Web服務(wù)器網(wǎng)關(guān)接口,主要是規(guī)范了Web服務(wù)器和Web應(yīng)用之間的交互,WSGI將Django分成了三類,服務(wù)器,APP,中間件。服務(wù)器就是用來(lái)監(jiān)聽某端口,APP用來(lái)調(diào)用某個(gè)函數(shù),而中間件則位于兩者中間,相當(dāng)于一道門,起審核承接等作用。但是WSGI始終是為同步世界編寫的,無(wú)法編寫異步對(duì)象。因此,ASGI誕生了。

2,ASGI:Async Sever Gateway Interface,說(shuō)白了,就是相當(dāng)于WSGI+異步功能,而要調(diào)用WebSocket,Django就需要使用ASGI接口。

三、Django開發(fā)聊天室或信息推送

第一步:下載Channels模塊

pip install channels

第二步:創(chuàng)建Django項(xiàng)目

Django-admin startproject websocket

創(chuàng)建后會(huì)看到Django3.0以后自存在asgi.py文件

第三步:創(chuàng)建一個(gè)APP應(yīng)用

python manage.py startapp websocket_demo

第四步:進(jìn)入settings.py模塊,進(jìn)行配置

首先在INSTALLED_APPS添加channels和websocket_demo

然后添加再在settings中添加ASGI應(yīng)用

第五步:在創(chuàng)建的APP中創(chuàng)建routing.py文件以及進(jìn)入asgi.py模塊進(jìn)行修改如下:

import os
 
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from websocket_demo import routing
 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web_socket.settings')
 
application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(routing.websocket_urlpatterns),
 
})

圖中代碼很容易理解:將服務(wù)器的請(qǐng)求分成了兩類,http請(qǐng)求則走默認(rèn)的asgi APP流程,是Websocket請(qǐng)求則進(jìn)入U(xiǎn)RL路由,即websocket_demo創(chuàng)建的routing.py文件

第六步,在websocket_demo的APP中views視圖下創(chuàng)建chat.py并且配置routing.py的文件:

from django.urls import re_path
from websocket_demo.views import chat
 
websocket_urlpatterns = [
    re_path(r'chat/(?P<group>\w+)/$', chat.ChatConsumer.as_asgi()),
]

使用正則路徑匹配chat/數(shù)字/的路徑,是則進(jìn)入chat.py文件中的CharConsumer函數(shù)

第七步,在urls.py中配置路由,指向websocket_demo中的chat.py文件

from django.urls import path, include
from websocket_demo.views import chat
 
urlpatterns = [
    path('index/', chat.chat)
]

第八步,編寫chat.py文件的內(nèi)容如下:

from django.shortcuts import render
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
from datetime import datetime
 
def chat(request):
    group_number = request.GET.get('num')
    return render(request, 'web/index.html', context)
 
class ChatConsumer(WebsocketConsumer):
 
    def websocket_connect(self, message):
        self.accept()
        group = self.scope['url_route']['kwargs'].get("group")
        async_to_sync(self.channel_layer.group_add)(group, self.channel_name)
 
    def websocket_receive(self, message):
        group = self.scope['url_route']['kwargs'].get("group")
        async_to_sync(self.channel_layer.group_send)(group, {"type": "chat", 'message': message})
 
    def chat(self, event):
        text = event['message']['text']
        self.send(text)
 
    def websocket_disconnect(self, message):
        group = self.scope['url_route']['kwargs'].get("group")
        async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)
        print('客戶端斷開連接了')
        raise StopConsumer()

首先第一個(gè)函數(shù)的意思是,進(jìn)入index頁(yè)面后會(huì)先進(jìn)入chat函數(shù),獲取URL中請(qǐng)求的參數(shù)num,渲染到index.html頁(yè)面,然后index.html頁(yè)面使用javascript發(fā)起websocket請(qǐng)求,發(fā)起websocket請(qǐng)求后,ASGI服務(wù)器通過(guò)"websocket": URLRouter(routing.websocket_urlpatterns)路由訪問(wèn)routing文件,routing文件指向了ChatConsumer(WebsocketConsumer)類。

第二個(gè)函數(shù)ChatConsumer(WebsocketConsumer)類對(duì)websocket請(qǐng)求進(jìn)行了處理,接收websocket的請(qǐng)求后獲取組號(hào)即num的值,然后接收websocket發(fā)送的信息后調(diào)用chat函數(shù)將收到的信息同等的發(fā)送回去,websocket_disconnet則是客戶端斷開請(qǐng)求后觸發(fā)的函數(shù)。

前端index.html的文件如下:

  reset.min.css文件:

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

style.css文件:

*, *:before, *:after {
  box-sizing: border-box;
}
:root {
  --white: #fff;
  --black: #000;
  --bg: #f8f8f8;
  --grey: #999;
  --dark: #1a1a1a;
  --light: #e6e6e6;
  --wrapper: 1000px;
  --blue: #00b0ff;
}
body {
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 400;
  background-image: url("../img/image.jpg");
  background-size: cover;
  background-repeat: none;
}
.wrapper {
  position: relative;
  left: 50%;
  width: var(--wrapper);
  height: 800px;
  -webkit-transform: translate(-50%, 0);
          transform: translate(-50%, 0);
}
.container {
  position: relative;
  top: 50%;
  left: 50%;
  width: 80%;
  height: 75%;
  background-color: var(--white);
  -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
}
.container .left {
  float: left;
  width: 37.6%;
  height: 100%;
  border: 1px solid var(--light);
  background-color: var(--white);
}
.container .left .top {
  position: relative;
  width: 100%;
  height: 96px;
  padding: 29px;
}
.container .left .top:after {
  position: absolute;
  bottom: 0;
  left: 50%;
  display: block;
  width: 80%;
  height: 1px;
  content: '';
  background-color: var(--light);
  -webkit-transform: translate(-50%, 0);
          transform: translate(-50%, 0);
}
.container .left input {
  float: left;
  width: 188px;
  height: 42px;
  padding: 0 15px;
  border: 1px solid var(--light);
  background-color: #eceff1;
  border-radius: 21px;
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 400;
}
.container .left input:focus {
  outline: none;
}
.container .left a.search {
  display: block;
  float: left;
  width: 42px;
  height: 42px;
  margin-left: 10px;
  border: 1px solid var(--light);
  background-color: var(--blue);
  background-image: url("../img//name-type.png");
  background-repeat: no-repeat;
  background-position: top 12px left 14px;
  border-radius: 50%;
}
.container .left .people {
  margin-left: -1px;
  border-right: 1px solid var(--light);
  border-left: 1px solid var(--light);
  width: calc(100% + 2px);
}
.container .left .people .person {
  position: relative;
  width: 100%;
  padding: 12px 10% 16px;
  cursor: pointer;
  background-color: var(--white);
}
.container .left .people .person:after {
  position: absolute;
  bottom: 0;
  left: 50%;
  display: block;
  width: 80%;
  height: 1px;
  content: '';
  background-color: var(--light);
  -webkit-transform: translate(-50%, 0);
          transform: translate(-50%, 0);
}
.container .left .people .person img {
  float: left;
  width: 40px;
  height: 40px;
  margin-right: 12px;
  border-radius: 50%;
}
.container .left .people .person .name {
  font-size: 14px;
  line-height: 22px;
  color: var(--dark);
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 600;
}
.container .left .people .person .time {
  font-size: 14px;
  position: absolute;
  top: 16px;
  right: 10%;
  padding: 0 0 5px 5px;
  color: var(--grey);
  background-color: var(--white);
}
.container .left .people .person .preview {
  font-size: 14px;
  display: inline-block;
  overflow: hidden !important;
  width: 70%;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--grey);
}
.container .left .people .person.active, .container .left .people .person:hover {
  margin-top: -1px;
  margin-left: -1px;
  padding-top: 13px;
  border: 0;
  background-color: var(--blue);
  width: calc(100% + 2px);
  padding-left: calc(10% + 1px);
}
.container .left .people .person.active span, .container .left .people .person:hover span {
  color: var(--white);
  background: transparent;
}
.container .left .people .person.active:after, .container .left .people .person:hover:after {
  display: none;
}
.container .right {
  position: relative;
  float: left;
  width: 62.4%;
  height: 100%;
}
.container .right .top {
  width: 100%;
  height: 47px;
  padding: 15px 29px;
  background-color: #eceff1;
}
.container .right .top span {
  font-size: 15px;
  color: var(--grey);
}
.container .right .top span .name {
  color: var(--dark);
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 600;
}
.container .right .chat {
  position: relative;
  display: none;
  overflow: hidden;
  padding: 0 35px 92px;
  border-width: 1px 1px 1px 0;
  border-style: solid;
  border-color: var(--light);
  height: calc(100% - 48px);
  justify-content: flex-end;
  flex-direction: column;
}
.container .right .chat.active-chat {
  display: block;
  display: flex;
}
.container .right .chat.active-chat .bubble {
  transition-timing-function: cubic-bezier(0.4, -0.04, 1, 1);
}
.container .right .chat.active-chat .bubble:nth-of-type(1) {
  -webkit-animation-duration: 0.15s;
          animation-duration: 0.15s;
}
.container .right .chat.active-chat .bubble:nth-of-type(2) {
  -webkit-animation-duration: 0.3s;
          animation-duration: 0.3s;
}
.container .right .chat.active-chat .bubble:nth-of-type(3) {
  -webkit-animation-duration: 0.45s;
          animation-duration: 0.45s;
}
.container .right .chat.active-chat .bubble:nth-of-type(4) {
  -webkit-animation-duration: 0.6s;
          animation-duration: 0.6s;
}
.container .right .chat.active-chat .bubble:nth-of-type(5) {
  -webkit-animation-duration: 0.75s;
          animation-duration: 0.75s;
}
.container .right .chat.active-chat .bubble:nth-of-type(6) {
  -webkit-animation-duration: 0.9s;
          animation-duration: 0.9s;
}
.container .right .chat.active-chat .bubble:nth-of-type(7) {
  -webkit-animation-duration: 1.05s;
          animation-duration: 1.05s;
}
.container .right .chat.active-chat .bubble:nth-of-type(8) {
  -webkit-animation-duration: 1.2s;
          animation-duration: 1.2s;
}
.container .right .chat.active-chat .bubble:nth-of-type(9) {
  -webkit-animation-duration: 1.35s;
          animation-duration: 1.35s;
}
.container .right .chat.active-chat .bubble:nth-of-type(10) {
  -webkit-animation-duration: 1.5s;
          animation-duration: 1.5s;
}
.container .right .write {
  position: absolute;
  bottom: 29px;
  left: 30px;
  height: 42px;
  padding-left: 8px;
  border: 1px solid var(--light);
  background-color: #eceff1;
  width: calc(100% - 58px);
  border-radius: 5px;
}
.container .right .write input {
  font-size: 16px;
  float: left;
  width: 347px;
  height: 40px;
  padding: 0 10px;
  color: var(--dark);
  border: 0;
  outline: none;
  background-color: #eceff1;
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 400;
}
.container .right .write .write-link.attach:before {
  display: inline-block;
  float: left;
  width: 20px;
  height: 42px;
  content: '';
  background-image: url("../img/attachment.png");
  background-repeat: no-repeat;
  background-position: center;
}
.container .right .write .write-link.smiley:before {
  display: inline-block;
  float: left;
  width: 20px;
  height: 42px;
  content: '';
  background-image: url("../img/smiley.png");
  background-repeat: no-repeat;
  background-position: center;
}
.container .right .write .write-link.send:before {
  display: inline-block;
  float: left;
  width: 20px;
  height: 42px;
  margin-left: 11px;
  content: '';
  background-image: url("../img/send.png");
  background-repeat: no-repeat;
  background-position: center;
}
.container .right .bubble {
  font-size: 16px;
  position: relative;
  display: inline-block;
  clear: both;
  margin-bottom: 8px;
  padding: 13px 14px;
  vertical-align: top;
  border-radius: 5px;
}
.container .right .bubble:before {
  position: absolute;
  top: 19px;
  display: block;
  width: 8px;
  height: 6px;
  content: '\00a0';
  -webkit-transform: rotate(29deg) skew(-35deg);
          transform: rotate(29deg) skew(-35deg);
}
.container .right .bubble.you {
  float: left;
  color: var(--white);
  background-color: var(--blue);
  align-self: flex-start;
  -webkit-animation-name: slideFromLeft;
          animation-name: slideFromLeft;
}
.container .right .bubble.you:before {
  left: -3px;
  background-color: var(--blue);
}
.container .right .bubble.me {
  float: right;
  color: var(--dark);
  background-color: #eceff1;
  align-self: flex-end;
  -webkit-animation-name: slideFromRight;
          animation-name: slideFromRight;
}
.container .right .bubble.me:before {
  right: -3px;
  background-color: #eceff1;
}
.container .right .conversation-start {
  position: relative;
  width: 100%;
  margin-bottom: 27px;
  text-align: center;
}
.container .right .conversation-start span {
  font-size: 14px;
  display: inline-block;
  color: var(--grey);
}
.container .right .conversation-start span:before, .container .right .conversation-start span:after {
  position: absolute;
  top: 10px;
  display: inline-block;
  width: 30%;
  height: 1px;
  content: '';
  background-color: var(--light);
}
.container .right .conversation-start span:before {
  left: 0;
}
.container .right .conversation-start span:after {
  right: 0;
}
@keyframes slideFromLeft {
  0% {
    margin-left: -200px;
    opacity: 0;
  }
  100% {
    margin-left: 0;
    opacity: 1;
  }
}
@-webkit-keyframes slideFromLeft {
  0% {
    margin-left: -200px;
    opacity: 0;
  }
  100% {
    margin-left: 0;
    opacity: 1;
  }
}
@keyframes slideFromRight {
  0% {
    margin-right: -200px;
    opacity: 0;
  }
  100% {
    margin-right: 0;
    opacity: 1;
  }
}
@-webkit-keyframes slideFromRight {
  0% {
    margin-right: -200px;
    opacity: 0;
  }
  100% {
    margin-right: 0;
    opacity: 1;
  }
}

index.js文件:  

document.querySelector('.chat[data-chat=person2]').classList.add('active-chat');
document.querySelector('.person[data-chat=person2]').classList.add('active');
 
var friends = {
  list: document.querySelector('ul.people'),
  all: document.querySelectorAll('.left .person'),
  name: '' },
 
chat = {
  container: document.querySelector('.container .right'),
  current: null,
  person: null,
  name: document.querySelector('.container .right .top .name') };
 
 
friends.all.forEach(function (f) {
  f.addEventListener('mousedown', function () {
    f.classList.contains('active') || setAciveChat(f);
  });
});
 
function setAciveChat(f) {
  friends.list.querySelector('.active').classList.remove('active');
  f.classList.add('active');
  chat.current = chat.container.querySelector('.active-chat');
  chat.person = f.getAttribute('data-chat');
  chat.current.classList.remove('active-chat');
  chat.container.querySelector('[data-chat="' + chat.person + '"]').classList.add('active-chat');
  friends.name = f.querySelector('.name').innerText;
  chat.name.innerHTML = friends.name;
}

index.html文件:

{% load static from static %}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>聊天窗口界面</title>
 
<link  rel="stylesheet">
<link rel="stylesheet" href="{% static 'web/chat/css/reset.min.css' %}">
<link rel="stylesheet" href="{% static 'web/chat/css/style.css' %}">
 
</head>
<body>
 
<div class="wrapper">
	<div class="container">
        <div class="left">
            <div class="top">
                <input type="text" placeholder="Search" />
                <a href="javascript:;" class="search"></a>
            </div>
            <ul class="people">
                <li class="person" data-chat="person2">
                    <img src="/static/myadmin/dist/img/user2-160x160.jpg" alt="" />
                    <span class="name">{{admin_name}}</span>
                    <span class="preview">I was wondering...</span>
                </li>
            </ul>
        </div>
        <div class="right">
            <div class="top"><span>To: <span class="name">{{admin_name}}</span></span></div>
            <div class="chat" data-chat="person2" id="chat-send" >
                <div class="conversation-start">
                    <span>{{time}}</span>
                </div>
            </div>
            <div class="write">
                <a href="javascript:;" class="write-link attach"></a>
                <input type="text" id="text"/>
                <a href="javascript:;" class="write-link smiley"></a>
                <a onclick="sendMessage()"  class="write-link send"></a>
            </div>
        </div>
    </div>
</div>
 
<script  src="{% static 'web/chat/js/index.js' %}"></script>
<script type="text/javascript">
    var socket=new WebSocket("ws://127.0.0.1:8000/chat/{{group_number}}/");
    socket.onopen = function(event)
	{
	var tag=document.getElementById("chat-send");
	var d=document.createElement("div");
	d.className="bubble you";
	d.innerHTML ="連接成功";
	tag.appendChild(d);
	}
    function sendMessage(){
	let text=document.getElementById("text");
	var tag=document.getElementById("chat-send");
	var d=document.createElement("div");
	d.className="bubble me";
	d.innerHTML =text.value;
	tag.appendChild(d);
	socket.send(text.value);
	text.value=" ";
	}
	socket.onclose = function(){
	var tag=document.getElementById("chat-send");
	var d=document.createElement("div");
	d.className="bubble you";
	d.innerHTML ="服務(wù)器主動(dòng)斷開連接";
	tag.appendChild(d);
}
socket.onmessage=function(event){
    var tag=document.getElementById("chat-send");
	var d=document.createElement("div");
	d.className="bubble you";
	d.innerHTML =event.data;
	tag.appendChild(d);
	}
</script>
<div style="text-align:center;margin:1px 0; font:normal 14px/24px 'MicroSoft YaHei';">
</div>
</body>
</html>

主要看javascript使用的函數(shù),首先進(jìn)行Websocket請(qǐng)ws://127.0.0.1:8000/chat/{{group_number}}/,然后分別的通過(guò)websocket發(fā)送信息,接受信息。

第九步,啟動(dòng)manage.py文件,同時(shí)打開兩個(gè)頁(yè)面觀看效果:

可以看到,某個(gè)用戶發(fā)送的信息,將會(huì)被服務(wù)器發(fā)送到同一聊天室的所有客戶端,實(shí)現(xiàn)了信息推送的功能。 

但是要實(shí)現(xiàn)一對(duì)一聊天的功能,目前實(shí)現(xiàn)是沒有思路,有大神看到煩請(qǐng)指點(diǎn)指點(diǎn)。

總結(jié)

到此這篇關(guān)于Django利用Channels+websocket開發(fā)聊天室的文章就介紹到這了,更多相關(guān)Django開發(fā)聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Python和NLTK進(jìn)行文本預(yù)處理示例詳解

    使用Python和NLTK進(jìn)行文本預(yù)處理示例詳解

    文將介紹如何使用Python編程語(yǔ)言和NLTK(Natural Language Toolkit)庫(kù)進(jìn)行文本預(yù)處理,為后續(xù)的文本分析和機(jī)器學(xué)習(xí)任務(wù)做準(zhǔn)備,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • python讀取目錄下所有的jpg文件,并顯示第一張圖片的示例

    python讀取目錄下所有的jpg文件,并顯示第一張圖片的示例

    今天小編就為大家分享一篇python讀取目錄下所有的jpg文件,并顯示第一張圖片的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • matplotlib subplot繪制多個(gè)子圖的方法示例

    matplotlib subplot繪制多個(gè)子圖的方法示例

    這篇文章主要介紹了matplotlib subplot繪制多個(gè)子圖的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Python中常見的矩陣運(yùn)算詳解

    Python中常見的矩陣運(yùn)算詳解

    這篇文章主要介紹了Python中常見的矩陣運(yùn)算詳解,所謂的數(shù)據(jù)處理,其本質(zhì)大都可以歸為矩陣運(yùn)算,因?yàn)樾枰幚淼臄?shù)據(jù)大都是矩陣或向量的形式,一個(gè)工具適不適合做數(shù)據(jù)處理,一個(gè)重要的指標(biāo)的就是支不支持矩陣運(yùn)算,需要的朋友可以參考下
    2023-08-08
  • Python 的類、繼承和多態(tài)詳解

    Python 的類、繼承和多態(tài)詳解

    本文通過(guò)實(shí)例給大家詳細(xì)解釋了Python 的類、繼承和多態(tài)的定義和用法,非常實(shí)用,有需要的小伙伴可以參考下
    2017-07-07
  • 詳解Django 中是否使用時(shí)區(qū)的區(qū)別

    詳解Django 中是否使用時(shí)區(qū)的區(qū)別

    本篇文章主要介紹了詳解Django 中是否使用時(shí)區(qū)的區(qū)別,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Python函數(shù)中閉包和延遲綁定詳情

    Python函數(shù)中閉包和延遲綁定詳情

    這篇文章主要介紹了Python函數(shù)中閉包和延遲綁定詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • 基于Python實(shí)現(xiàn)簡(jiǎn)單的定時(shí)器詳解

    基于Python實(shí)現(xiàn)簡(jiǎn)單的定時(shí)器詳解

    所謂定時(shí)器,是指間隔特定時(shí)間執(zhí)行特定任務(wù)的機(jī)制。幾乎所有的編程語(yǔ)言,都有定時(shí)器的實(shí)現(xiàn)。這篇文章主要介紹的是通過(guò)Python實(shí)現(xiàn)的定時(shí)器,感興趣的可以跟隨小編學(xué)習(xí)一下
    2021-12-12
  • 一次python-flask藍(lán)圖的踩坑記錄

    一次python-flask藍(lán)圖的踩坑記錄

    簡(jiǎn)單來(lái)說(shuō),藍(lán)圖就是一個(gè)存儲(chǔ)操作路由映射方法的容器,主要用來(lái)實(shí)現(xiàn)客戶端請(qǐng)求和URL相互關(guān)聯(lián)的功能,在Flask中,使用藍(lán)圖可以幫助我們實(shí)現(xiàn)模塊化應(yīng)用的功能,這篇文章主要給大家介紹了關(guān)于python-flask藍(lán)圖踩坑的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Jupyter Notebook 如何修改字體和大小以及更改字體樣式

    Jupyter Notebook 如何修改字體和大小以及更改字體樣式

    這篇文章主要介紹了Jupyter Notebook 如何修改字體和大小以及更改字體樣式的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評(píng)論