دوستان عزیز در ادامه اموزشهای امروزکه در مورد python به بحث ماژول ها در پایتون (module) میپردازیم. ماژول به شما این امکان را می دهد که کدهای خود را در پایتون سازمان دهی کنید. گروه بندی کدهای مرتبط با هم در یک ماژول، خوانایی کد و قابلیت استفاده از آن را بهبود می بخشد. ماژول یک شی است که دارای متغیرهای عضو (attribute) می باشد. این متغیرها را می توان bind(متصل) کرده و مورد ارجاع (reference) قرار داد.

ماژول درواقع یک فایل است که حاوی کد پایتون می باشد. ماژول توابع، کلاس ها و متغیرهایی را در اختیار شما قرار می دهد. ماژول همچنین می تواند دربردارنده ی کد اجرایی باشد.

مثال:

کد پایتون ماژول aname، داخل فایل aname.py جای گذاری می شود. در زیر مثالی از یک ماژول ساده (support.py) را مشاهده می کنید:

def print_func( par ):

print “Hello : “, par

return

دستور import

می توان با استفاده از دستور import، یک source file پایتون را در source file دیگری مورد استفاده قرار داد. نحوه ی استفاده از دستور import به ترتیب زیر می باشد:

import module1[, module2[,… moduleN]

هنگامی که مفسر با دستور import مواجه می شود، اگر آن ماژول در search path (مسیر جستجو) موجود باشد، ماژول مربوطه را وارد برنامه ی جاری می کند. search path، لیستی از پوشه ها (directory) است که مفسر در آن ها جستجو کرده و در صورت یافتن ماژول مورد نظر آن را وارد می کند. برای مثال، به منظور وارد کردن ماژول hello.py، می بایست دستور زیر را بالای اسکریپت درج نمایید:

#!/usr/bin/python

# Import module support

import support

# Now you can call defined function that module as follows

support.print_func(“Zara”)

خروجی:

Hello : Zara

یک ماژول، صرف نظر اینکه چندبار وارد (import) می شود، فقط یکبار بارگذاری می گردد. در صورت وجود چندین نمونه از دستور import، این امر مانع از این می شود که ماژول بارها و بارها اجرا شود.

The from…import Statement

دستور from، به شما اجازه می دهد متغیرهای عضو (attribute) را از یک ماژول وارد فضای نامی جاری کنید. طریقه ی بکار بردن دستور from…import در زیر نمایش داده شده است:

from modname import name1[, name2[, … nameN]]

برای مثال، جهت وارد کردن تابع fibonacci از ماژول fib، دستور زیر را استفاده نمایید:

from fib import fibonacci

این دستور کل ماژول fib را در فضای نام جاری وارد نمی کند، بلکه صرفا آیتم fibonacci را از ماژول fib داخل جدول سراسری symbol ماژول import شده وارد می نماید.

دستور from…import *

همچنین می توان تمامی اسم ها را از یک ماژول، وارد فضای نامی جاری کرد. این کار با استفاده از دستور زیر امکان پذیر می باشد:

from modname import *

دستور یاد شده، روشی آسان برای وارد کردن تمامی آیتم های مورد نظر از یک ماژول در فضای نام جاری می باشد. با این حال توصیه می شود از این دستور فقط مواقع ضروری استفاده کنید.

مکان یابی ماژول

به هنگام وارد کردن یک ماژول، مفسر زبان پایتون به ترتیب شرح داده شده در زیر به دنبال ماژول مورد نظر می گردد.

۱٫ پوشه ی جاری.

۲٫ در صورت نیافتن ماژول، پایتون هر پوشه (directory) را در shell variableکه PYTHONPATH نام دارد جستجو می کند.

۳٫ در صورت موفق نبودن دو روش ذکر شده، پایتون مسیر پیش فرض را سرچ می کند. در محیط UNIX، این مسیر پیش فرض /usr/local/lib/python/ می باشد.

مسیری که ماژول در آن جستجو می شود (module search path)، داخل ماژول system module در قالب متغیر sys.path ذخیره می شود. متغیر sys.path حاوی پوشه ی جاری، متغیر PYTHONPATH است و مقدار پیش فرض آن به مسیر نصب بستگی دارد.

متغیر PYTHONPATH

PYTHONPATH، همان طور که پیش تر در این سری آمورشی تشریح شد، یک environment variable (متغیرهای محیطی مجموعه‌ای از مقادیر نام‌گذاری‌شده هستند که قادراند چگونگی رفتار کردن پروسه های در حال اجرا را تغییر داده و بر روی آنها تاثیر بگذارند. متغیرهای محیطی، از فرایند parent به فرایندهای child به ارث می‌رسند. این متغیرها بخشی از محیط عملیاتی هستند که فرایند در آن اجرا می‌شود.) می باشد که از لیستی از پوشه ها (directory) تشکیل شده است. سینتکس متغیر نام برده مشابه shell variable، PATH می باشد.

در زیر مثالی از متغیر PYTHONPATH در سیستم عامل ویندوز را می بینید:

set PYTHONPATH=c:\python20\lib;

نمونه ای از متغیر محیطی PYTHONPATH از سیستم UNIX:

set PYTHONPATH=/usr/local/lib/python

فضای نامی و تعیین حوزه ی دسترسی

متغیرها اسم ها یا شناسه هایی هستند که به اشیا نگاشت (map) می شوند. فضای نام یک dictionary از اسم متغیر (کلید) و اشیای مرتبط با آن (مقادیر) هستند.

دستور پایتون می تواند به متغیرهایی که در فضای نام محلی و همچنین در فضای نام سراسری قرار دارد، دسترسی داشته باشد.چنانچه متغیر سراسری و محلی هر دو دارای اسمی یکسان باشند، متغیر محلی بر متغیر سراسری اولویت دارد.

هر تابع دارای فضای نام محلی و مختص به خود است. متدهای کلاس نیز از همان قوانین تعیین حوزه ی دسترسی که توابع معمولی دنبال می کنند، پیروی می کنند.

زبان پایتون برآورد می کند متغیرها سراسری هستند یا محلی. بدین معنی که فرض می گیرد هر متغیری که در یک تابع مقداردهی می شود، نسبت به آن تابع محلی می باشد.

از این رو، جهت تخصیص یک مقدار به متغیر سراسری در حوزه ی یک تابع، ابتدا بایستی از دستور سراسری استفاده کنید.

دستور global VarName به زبان پایتون اطلاع می دهد که VarName یک متغیر سراسری است، در پی آن پایتون جستجو برای متغیر مورد نظر در فضای نام محلی را متوقف می سازد.

فرض بگیرید، یک متغیر به نام Money در فضای نام سراسری تعریف کرده ایم. سپس داخل تابع، متغیر ذکر شده را مقداردهی می کنیم. به دنبال آن پایتون متغیر Money را یک متغیر محلی در نظر می گیرد. با این حال، پیش از اینکه متغیر محلی Money را تنظیم (set) کنیم، سعی کردیم به مقدار آن دسترسی پیدا کنیم. در نتیجه با خطای UnboundLocalError مواجه می شویم. برای رفع آن، دستور سراسری global Money را از حالت comment خارج می کنیم:

#!/usr/bin/python

Money = 2000

def AddMoney():

# Uncomment the following line to fix the code:

# global Money

Money = Money + 1

print Money

AddMoney()

print Money

تابع dir()

تابع توکار dir() لیست مرتب سازی شده ای برمی گرداند که حاوی رشته های متعدد می باشد. این رشته ها دربردارنده ی اسم ماژول ها می باشد.

لیستی که این تابع بازمی گرداند، دربردارنده ی ماژول ها، متغیرها و توابع می باشد که در ماژول تعریف شده اند. مثال:

#!/usr/bin/python

# Import built-in module math

import math

content = dir(math)

print content

نتیجه:

[‘__doc__’, ‘__file__’, ‘__name__’, ‘acos’, ‘asin’, ‘atan’,

‘atan2’, ‘ceil’, ‘cos’, ‘cosh’, ‘degrees’, ‘e’, ‘exp’,

‘fabs’, ‘floor’, ‘fmod’, ‘frexp’, ‘hypot’, ‘ldexp’, ‘log’,

‘log10’, ‘modf’, ‘pi’, ‘pow’, ‘radians’, ‘sin’, ‘sinh’,

‘sqrt’, ‘tan’, ‘tanh’]

در اینجا، متغیر رشته ای – name – اسم ماژول می باشد و – file – اسم فایل می باشد که ماژول از آن بارگذاری می شود.

The globals() and locals() Functions −

توابع globals() و locals() اسم های فضای نام محلی و سراسری را بسته به مکانی که از آن فراخوانی می شود، برمی گرداند.

اگر تابع locals() از داخل یک تابع فراخوانی شود، در آن صورت تمامی اسم هایی که به صورت محلی قابل دسترسی می باشد، با صدا خوردن تابع نام برده برگردانده می شوند.

اگر تابع globals() ار درون تابع صدا زده شود، در آن صورت کلیه ی اسم هایی که به صورت سراسری قابل دسترسی هستند، با فراخوانی تابع ذکر شده بازیابی می شوند.

خروجی این دو تابع، متغیری از نوع داده ای dictionary خواهد بود. برای استخراج اسم ها، کافی است تابع keys() را مورد استفاده قرار دهید.

تابع reload()

هنگامی که ماژول در یک اسکریپت import می شود، کدی که در بالاترین بخش ماژول قرار می گیرد، تنها یکبار اجرا می شود.

بنابراین، اگر می خواهید کدی که در بالاترین قسمت یک ماژول قرار دارد را مجددا اجرا کنید، بایستی تابع reload() را مورد استفاده قرار دهید.

تابع reload() یک ماژول که قبلا وارد شده بود را مجددا import می کند. نحوه ی استفاده از آن به ترتیب زیر می باشد:

reload(module_name)

در این نمونه، module_name در واقع اسم ماژولی است که می خواهید مجددا بارگذاری یا reloadشود، نه رشته ای که حاوی اسم ماژول است. به عنوان مثال، برای بارگذاری مجدد ماژول hello، می بایست دستور زیر را وارد نمایید:

reload(hello)

پکیج ها در پایتون

پکیج یک پوشه ی فایل یا file directory است که ساختار سلسله مراتبی دارد و محیط برنامه ی پایتون را که از ماژول ها، subpackage ها و sub-subpackage ها تشکیل شده است را مشخص می کند.

فرض کنید، فایل Pots.py در پوشه ی Phone جای گرفته است. source code این فایل به ترتیب زیر می باشد:

#!/usr/bin/python

def Pots():

print “I’m Pots Phone”

به طور مشابه، دو فایل دیگر داریم که با همان اسم دربردارنده ی توابع متفاوتی هستند.

۱٫ فایل Phone/Isdn.py حاوی تابع Isdn()

۲٫ فایل Phone/G3.py دربردارنده ی تابع G3()

حال یک فایل __init__.py دیگر در پوشه ی Phone ایجاد کنید:

Phone/__init__.py

برای اینکه بتوانید پس از import کردن Phone، تمامی توابع خود را در آماده ی استفاده داشته باشید، بایستی دستور صریح import را در __init__.py به صورت زیر قرار دهید:

from Pots import Pots

from Isdn import Isdn

from G3 import G3

بعد از اینکه خطوط فوق را به فایل __init__.py، اضافه کردید، با وارد کردن پکیج Phone، تمامی این کلاس ها در دسترس خواهند بود.

#!/usr/bin/python

# Now import your Phone Package.

import Phone

Phone.Pots()

Phone.Isdn()

Phone.G3()

نتیجه:

I’m Pots Phone

I’m 3G Phone

I’m ISDN Phone