99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)
深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)
2018-02-08
收藏

深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)

現(xiàn)在越來越多的人使用virtualenv虛擬環(huán)境部署Python項(xiàng)目,包括針對框架的實(shí)例文件夾與版本控制布置,這里我們就來整理關(guān)于深度定制Python的Flask框架開發(fā)環(huán)境的一些技巧總結(jié)

Flask 環(huán)境配置

你的應(yīng)用程序可能需要大量的軟件包才能正常的工作。如果都不需要 Flask 包的話,你有可能讀錯(cuò)了教程。當(dāng)應(yīng)用程序運(yùn)行的時(shí)候,你的應(yīng)用程序的 環(huán)境 基本上是所有一切事情的根基。我們是幸運(yùn)的,因?yàn)橛性S多方式使得我們能夠輕松地管理我們的環(huán)境。

使用 virtualenv 管理你的環(huán)境

virtualenv 是用于在所謂 虛擬環(huán)境 中隔離你的應(yīng)用程序的一個(gè)工具。一個(gè)虛擬環(huán)境是包含了你的應(yīng)用依賴的軟件的一個(gè)目錄。一個(gè)虛擬環(huán)境也能夠改變你的環(huán)境變量以維持你的開發(fā)環(huán)境包含的環(huán)境變量。不用下載包,像 Flask, 到你系統(tǒng)級或者用戶級的包目錄,我們可以下載它們到一個(gè)獨(dú)立的并且只為我們應(yīng)用使用的目錄。這就可以很容易地指定使用的 Python 的版本以及每一個(gè)項(xiàng)目依賴的包。

Virtualenv 也可以讓你在不同的項(xiàng)目中使用相同的包的不同版本。這種靈活性可能是十分重要的,如果你正使用一個(gè)舊的系統(tǒng)并且它的上面有幾個(gè)項(xiàng)目需要不同的版本。

當(dāng)使用 virtualenv 的時(shí)候,你通常只需要安裝幾個(gè)的 Python 包在你的系統(tǒng)上。其中一個(gè)就是 virtualenv 本身。你可以使用 Pip 來安裝 virtualenv 包。

一旦在你的系統(tǒng)上安裝了 virtualenv,你可以開始創(chuàng)建虛擬環(huán)境。前往你項(xiàng)目所在的目錄并且運(yùn)行 virtualenv 命令。它需要一個(gè)參數(shù),這個(gè)參數(shù)就是虛擬環(huán)境的目標(biāo)目錄。下面展示了它大概的樣子。

$ virtualenv venv
New python executable in venv/bin/python
Installing Setuptools...........[...].....done.
Installing Pip..................[...].....done.

virtualenv 創(chuàng)建一個(gè)新的目錄,依賴包將會(huì)安裝到這個(gè)目錄中。
一旦新的虛擬環(huán)境已經(jīng)創(chuàng)建,你必須激活它,通過發(fā)動(dòng)創(chuàng)建在虛擬環(huán)境里的 bin/activate 腳本。    
$ which python
/usr/local/bin/python
$ source venv/bin/activate
(venv)$ which python
/Users/robert/Code/myapp/venv/bin/python

bin/activate 腳本對你的 shell 環(huán)境變量進(jìn)行一些改變以致一切都指向新的虛擬環(huán)境而不是全局系統(tǒng)。你可以在上面的代碼塊中看到效果。激活后,python 命令指向虛擬環(huán)境的中 Python 的 bin 目錄。當(dāng)虛擬環(huán)境激活后,使用 Pip 安裝的依賴包會(huì)被下載到虛擬環(huán)境中而不是全局系統(tǒng)。

你可能會(huì)注意到 shell 中的提示符也已經(jīng)改變了。virtualenv 預(yù)先設(shè)定目前激活虛擬環(huán)境的名稱,因此你會(huì)知道你不是在全局系統(tǒng)上工作。

你可以通過運(yùn)行 deactivate 命令停用你的虛擬環(huán)境。

(venv)$ deactivate

virtualenvwrapper

virtualenvwrapper 是一個(gè)用于管理 virtualenv 創(chuàng)建的虛擬環(huán)境的軟件包。我不想提到這個(gè)工具,直到你看到了 virtualenv 的基礎(chǔ)知識以便你理解它改善了什么以及為什么我們應(yīng)該使用它。

上一部分創(chuàng)建的虛擬環(huán)境目錄會(huì)給你的項(xiàng)目庫帶來一些混亂。你只需要激活虛擬環(huán)境和它進(jìn)行交互,但是它不應(yīng)該出現(xiàn)在版本控制中,因此這個(gè)虛擬環(huán)境目錄就不應(yīng)該在這里。解決方案就是使用 virtualenvwrapper。這個(gè)軟件包會(huì)把所有你的虛擬環(huán)境放在一個(gè)目錄的方式,通常默認(rèn)是在 ~/.virtualenvs/。

要安裝 virtualenvwrapper,請按照文檔中的說明,文檔位于 http://virtualenvwrapper.readthedocs.org/en/latest/install.html 。

請確保在安裝 virtualenvwrapper 之前你已經(jīng)停用所有的虛擬環(huán)境。你需要把它安裝在全局系統(tǒng)中,而不是虛擬環(huán)境中。

現(xiàn)在,不用運(yùn)行 virtualenv 來創(chuàng)建一個(gè)環(huán)境,你需要運(yùn)行 mkvirtualenv:

$ mkvirtualenv rocket
New python executable in rocket/bin/python
Installing setuptools...........[...].....done.
Installing pip..................[...].....done.
(rocket)$

mkvirtualenv 在你虛擬環(huán)境目錄中創(chuàng)建一個(gè)文件夾并且為你激活虛擬環(huán)境。就像上面的 virtualenv 一樣,python 以及 pip 指向虛擬環(huán)境中而不是全局系統(tǒng)的二進(jìn)制文件。要激活一個(gè)特定的環(huán)境,使用命令:workon [environment name]。deactivate 仍然會(huì)停用虛擬環(huán)境。

安裝依賴包

隨著項(xiàng)目的發(fā)展,你會(huì)發(fā)現(xiàn)依賴包的列表會(huì)增大。需要幾十個(gè) Python 包來運(yùn)行一個(gè) Flask 應(yīng)用程序的情況并不少見。管理這些最簡單的方法是用一個(gè)簡單的文本文件。Pip 能夠生成一個(gè)列出所有已安裝的包的文本文件。在一個(gè)新的系統(tǒng)上,或者在一個(gè)新的剛創(chuàng)建的環(huán)境上也能讀取文件中的列表并且安裝它們中每一個(gè)。
pip freeze:
requirements.txt 是一個(gè)文本文件,它被許多 Flask 應(yīng)用程序用來列出運(yùn)行應(yīng)用所有需要的包。這個(gè)代碼塊用來說明如何創(chuàng)建這個(gè)文件接著下一個(gè)代碼塊用來說明在一個(gè)新環(huán)境中如果使用這個(gè)文件來安裝依賴包。    
(rocket)$ pip freeze > requirements.txt
$ workon fresh-env
(fresh-env)$ pip install -r requirements.txt
[...]
Successfully installed flask Werkzeug Jinja2 itsdangerous markupsafe
Cleaning up...
(fresh-env)$

人工管理依賴包

隨著項(xiàng)目的發(fā)展,你可能會(huì)發(fā)現(xiàn) pip freeze 列出的某些包實(shí)際上并不是運(yùn)行應(yīng)用必須的。你安裝這些包僅僅為開發(fā)用的。pip freeze 并不能區(qū)分,它僅僅列出目前已經(jīng)安裝的包。因此,你可能要手動(dòng)地管理這些依賴包。你可以分別把那些運(yùn)行應(yīng)用必須的包放入 require\_run.txt 以及那些開發(fā)應(yīng)用程序需要的包放入 require\_dev.txt 。

版本控制

選擇一個(gè)版本控制系統(tǒng)并且使用它。我推薦 Git。從我所看到的,Git 是這些天來新項(xiàng)目最流行的選擇。能夠刪除代碼而不必?fù)?dān)心犯了一個(gè)不可逆轉(zhuǎn)的錯(cuò)誤是非常寶貴的。你也可以讓你的項(xiàng)目擺脫大量注釋掉的代碼的困擾,因?yàn)槟憧梢詣h除它們,以后如有需要可以恢復(fù)它們。另外,你可以在 GitHub,Bitbucket 或者你自己的 Gitolite 服務(wù)器上備份整個(gè)項(xiàng)目。
置身版本控制之外的文件

我通常會(huì)讓一個(gè)文件置身版本控制之外有兩個(gè)原因:要么就是它會(huì)讓整個(gè)項(xiàng)目顯得混亂,要么它就是一個(gè)很隱私的密鑰/證書。編譯的 .pyc 文件和虛擬環(huán)境 — 如果由于某些原因你沒有使用 virtualenvwrapper — 就是讓項(xiàng)目顯得很混亂的例子。它們不需要在版本控制之中因?yàn)樗鼈兡軌蚍謩e地從 .py 文件和你的 requirements.txt 文件重新創(chuàng)建。

API 秘鑰,應(yīng)用程序秘鑰以及數(shù)據(jù)庫證書是很隱私的密鑰/證書的示例。它們不應(yīng)該出現(xiàn)在版本控制中因?yàn)樗鼈兊钠毓鈱⑹且粋€(gè)巨大的安全漏洞。

當(dāng)做跟安全有關(guān)的決定的時(shí)候,我總是喜歡假設(shè)我的版本庫將在某個(gè)時(shí)候變成公開的。這就意味著要保守秘密并且從不假設(shè)一個(gè)安全漏洞不會(huì)被發(fā)現(xiàn),“誰來猜猜他們能做到”這類型的假設(shè)被稱為通過隱匿來實(shí)現(xiàn)安全,這是十分槽糕的策略。

當(dāng)使用 Git 的時(shí)候,你可以在你的版本庫中創(chuàng)建名為 .gitignore 的一個(gè)特殊文件。在這個(gè)文件里,使用列表通配符來匹配文件名。任何匹配其中一個(gè)模式的文件名都會(huì)被 Git 給忽略掉。我推薦使用 .gitignore 來控制不需要版本控制的文件。例如:    
*.pyc
instance/
Instance 文件夾是用于以一種更安全地方式提供給你的應(yīng)用程序敏感配置變量。我將會(huì)在后面更多地談到它。

調(diào)試

1.調(diào)試模式

Flask 有一個(gè)稱為調(diào)試模式方便的功能。要打開調(diào)試功能的話,你只必須在你的開發(fā)配置中設(shè)置 debug = True。當(dāng)它打開的時(shí)候,服務(wù)器在代碼變化的時(shí)候自動(dòng)加載并且出錯(cuò)的時(shí)候會(huì)伴隨著一個(gè)堆棧跟蹤和一個(gè)交互式控制臺。

小心!不要在生產(chǎn)環(huán)境中使用調(diào)試模式。交互式控制臺允許執(zhí)行任意代碼并會(huì)是一個(gè)巨大的安全漏洞。

2.Flask-DebugToolbar

Flask-DebugToolbar 是另一個(gè)非常了不起的工具,它可以幫助在你的應(yīng)用程序中調(diào)試問題。在調(diào)試模式下,它會(huì)把一個(gè)側(cè)邊欄置于你的應(yīng)用程序的每一頁上。側(cè)邊欄提供了有關(guān) SQL 查詢,日志記錄,版本,模板,配置和其它有趣的信息,使得更容易地跟蹤問題。
看看快速入門中的 調(diào)試模式。在 Flask 官方文檔 中有一些關(guān)于錯(cuò)誤處理,日志記錄以及使用調(diào)試器等不錯(cuò)的信息。

Flask 工程配置

當(dāng)你學(xué)習(xí) Flask 的時(shí)候,配置看起來很簡單。你只要在 config.py 中定義一些變量接著一切就能工作了。當(dāng)你開始必須要管理生產(chǎn)應(yīng)用的配置的時(shí)候,這些簡單性開始消失了。你可能需要保護(hù) API 密鑰以及為不同的環(huán)境使用不同的配置(例如,開發(fā)和生產(chǎn)環(huán)境)。在本章節(jié)中我們會(huì)介紹 Flask 一些先進(jìn)的功能,它可以使得管理配置容易些。

簡單的例子

一個(gè)簡單的應(yīng)用程序可能不會(huì)需要任何這些復(fù)雜的功能。你可能只需要把 config.py 放在你的倉庫/版本庫的根目錄并且在 app.py 或者 yourapp/\\_init\\_.py 中加載它。

config.py 文件中應(yīng)該每行包含一個(gè)配置變量賦值。當(dāng)你的應(yīng)用程序初始化的時(shí)候,在 config.py 中的配置變量用于配置 Flask 和它的擴(kuò)展并且它們能夠通過 app.config 字典訪問到 – 例如,app.config["DEBUG"]。 
DEBUG = True # Turns on debugging features in Flask
BCRYPT_LEVEL = 12 # Configuration for the Flask-Bcrypt extension
MAIL_FROM_EMAIL = "robert@example.com" # For use in application emails

配置的變量可以被 Flask,它的擴(kuò)展或者你來使用。這個(gè)例子中, 每當(dāng)我們在一封事務(wù)性郵件中需要默認(rèn)的 “發(fā)件人” 的時(shí)候,我們可以使用 app.config["MAIL_FROM_EMAIL"] – 例如,密碼重置。把這些信息放置于一個(gè)配置變量中使得以后能夠容易地修改它。    
# app.py or app/__init__.pyfrom flask import Flask
app = Flask(__name__)
app.config.from_object('config')
# Now we can access the configuration variables via app.config["VAR_NAME"].

    DEBUG: 為你提供了調(diào)試錯(cuò)誤的一些方便的工具。 這包括一個(gè)基于 Web 的堆棧跟蹤和交互式的 Python 控制臺。在開發(fā)環(huán)境中設(shè)置成 True; 生產(chǎn)環(huán)境中設(shè)置成 False。
    SECRET\_KEY:這是 Flask 用來為 cookies 簽名的密鑰。 它也能被像 Flask-Bcrypt 類的擴(kuò)展使用。 你應(yīng)該在你的實(shí)例文件夾中定義它, 這樣可以遠(yuǎn)離版本控制。 你可以在下一個(gè)章節(jié)中閱讀更多關(guān)于示例文件夾的內(nèi)容。一般情況下這應(yīng)該是一個(gè)復(fù)雜的隨機(jī)值。
    BCRYPT\_LEVEL:如果你使用 Flask-Bcrypt 來散列用戶密碼的話, 你需要指定一個(gè)“循環(huán)”數(shù),這個(gè)數(shù)是在執(zhí)行散列密碼的 算法需要的。如果你不使用 Flask-Bcrypt,你可以 忽略這里。用于散列密碼的循環(huán)數(shù)越大,攻擊者猜測密碼 的時(shí)間會(huì)越長。同時(shí),循環(huán)數(shù)越大會(huì)增加散列密碼的時(shí)間。后面我們會(huì)給出在 Flask 應(yīng)用中 使用 Bcrypt 的一些最佳實(shí)踐。

確保在生產(chǎn)環(huán)境中 DEBUG 設(shè)置成 False。如果保留 DEBUG 為 True,它允許用戶在你的服務(wù)器上執(zhí)行任意的 Python。

實(shí)例文件夾

有時(shí)候你需要定義包含敏感信息的配置變量。我們想要從 config.py 中分離這些變量并且讓它們保留在倉庫/版本庫之外。你可能會(huì)隱藏像數(shù)據(jù)庫密碼以及 API 密鑰的一些敏感信息,或者定義于特定于指定機(jī)器的配置變量。為讓實(shí)現(xiàn)這些要求更加容易些,F(xiàn)lask 提供了一個(gè)叫做 instance folders 的功能。實(shí)例文件夾是倉庫/版本庫下的一個(gè)子目錄并且包含專門為這個(gè)應(yīng)用程序的實(shí)例的一個(gè)配置文件。我們不希望它提交到版本控制。    
config.py
requirements.txt
run.py
instance/
 config.py
yourapp/
 __init__.py
 models.py
 views.py
 templates/
 static/

使用實(shí)例文件夾
我們使用 app.config.from_pyfile() 來從一個(gè)實(shí)例文件夾中加載配置變量。當(dāng)我們調(diào)用 Flask() 來創(chuàng)建我們的應(yīng)用的時(shí)候,如果我們設(shè)置了 instance_relative_config=True, app.config.from_pyfile() 將會(huì)從 instance/ 目錄加載指定文件。
    
# app.py or app/__init__.py
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py')

現(xiàn)在我們可以像在 config.py 中那樣在 instance/config.py 中定義配置變量。你也應(yīng)該把你的實(shí)例文件夾加入到版本控制系統(tǒng)的忽略列表中。要使用 Git 做到這一點(diǎn)的話,你需要在 .gitignore 新的一行中添加 instance/ 。

密鑰

實(shí)例文件夾的隱私性成為在其里面定義不想暴露到版本控制的密鑰的最佳候選。這些密鑰可能包含了你的應(yīng)用的密鑰或者第三方 API 密鑰。如果你的應(yīng)用是開源的或者以后可能會(huì)公開的話,這一點(diǎn)特別重要。我們通常要求其他用戶或者貢獻(xiàn)者使用自己的密鑰。    
# instance/config.py
SECRET_KEY = 'Sm9obiBTY2hyb20ga2lja3MgYXNz'
STRIPE_API_KEY = 'SmFjb2IgS2FwbGFuLU1vc3MgaXMgYSBoZXJv'
SQLALCHEMY_DATABASE_URI= \\"postgresql://user:TWljaGHFgiBCYXJ0b3N6a2lld2ljeiEh@localhost/databasename"

基于環(huán)境的配置

如果在你的生產(chǎn)環(huán)境和開發(fā)環(huán)境中的差異非常小的話,你可能想要使用實(shí)例文件夾來處理配置的變化。定義在 'instance/config.py' 文件中的配置變量能夠覆蓋 'config.py' 中的值。你只需要在 'app.config.from_object()' 后調(diào)用 'app.config.from_pyfile()'。這樣用法的好處之一就是在不同的機(jī)器上修改你的應(yīng)用的配置。    
# config.py
DEBUG = False
SQLALCHEMY_ECHO = False
# instance/config.py
DEBUG = True
SQLALCHEMY_ECHO = True

在生產(chǎn)環(huán)境上,我們略去上面 'instance/-config.py' 中的配置變量,它會(huì)退回到定義在 'config.py' 中的值。

基于環(huán)境變量配置

實(shí)例文件夾不應(yīng)該出現(xiàn)在版本控制中。這就意味著你將無法跟蹤你的實(shí)例配置的變化。如果只是一、兩個(gè)變量這可能不是什么問題,但是如果你在不同的環(huán)境上(生產(chǎn),預(yù)升級,開發(fā),等等)配置都有些微調(diào)話,你就不會(huì)想要存在丟失它們的風(fēng)險(xiǎn)。
Flask 給我們選擇配置文件的能力,它可以基于一個(gè)環(huán)境變量的值來加載不同的配置文件。這就意味著在我們的倉庫/版本庫里,我們可以有多個(gè)配置文件并且總會(huì)加載正確的那一個(gè)。一旦我們有多個(gè)配置文件的話,我可以把它們移入它們自己 config 文件夾中。    
requirements.txt
run.py
config/
 __init__.py # Empty, just here to tell Python that it's a package.
 default.py
 production.py
 development.py
 staging.py
instance/
 config.py
yourapp/
 __init__.py
 models.py
 views.py
 static/
 templates/

在上面的文件列表中我們有多個(gè)不同的配置文件。
    config/default.py: 默認(rèn)的配置值,可用于所有的環(huán)境或者被個(gè)人的環(huán)境給覆蓋。
    config/development.py: 用于開發(fā)環(huán)境的配置值。這里你可能會(huì)指定本地?cái)?shù)據(jù)庫的 URI。
    config/production.py: 用于生產(chǎn)環(huán)境的配置值。在這里 DEBUG 一定要設(shè)置成 False。
    config/staging.py: 根據(jù)開發(fā)進(jìn)度,你可能會(huì)有一個(gè)模擬生產(chǎn)環(huán)境,這個(gè)文件主要用于這種場景。

為了決定要加載哪個(gè)配置文件,我們會(huì)調(diào)用 'app.config.from_envvar()'。    
# yourapp/\\_\\_init\\_\\_.py
app = Flask(__name__, instance_relative_config=True)
# Load the default configuration
app.config.from_object('config.default')
# Load the configuration from the instance folder
app.config.from_pyfile('config.py')
# Load the file specified by the APP\\_CONFIG\\_FILE environment variable# Variables defined here will override those in the default configuration
app.config.from_envvar('APP_CONFIG_FILE')

環(huán)境變量的值應(yīng)該是配置文件的絕對路徑。

我們?nèi)绾卧O(shè)置這個(gè)環(huán)境變量取決于我們運(yùn)行應(yīng)用所在的平臺。如果我們運(yùn)行在一個(gè)普通的 Linux 服務(wù)器上,我們可以編寫一個(gè)設(shè)置環(huán)境變量的 shell 腳本并且運(yùn)行 run.py。    
# start.sh
APP\\_CONFIG\\_FILE=/var/www/yourapp/config/production.py
python run.py

start.sh 對于每一個(gè)環(huán)境都是獨(dú)一無二的,因此它應(yīng)該被排除在版本控制之外。在 Heroku 上,我們需要使用 Heroku 工具來設(shè)置環(huán)境變量。這種設(shè)置方式也適用于其它的 PaaS 平臺。


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }