سلام دوستان ...در قسمت قبل آموزش پایتون مفاهیم زیر را یاد دادیم
معمولا اشیای دنباله با سایر اشیا از نوع دنباله مشابه، مقایسه می شوند. مقایسه از مرتب سازی واژگان استفاده می کند. در ابتدا، دو عنصر اول مقایسه می شوند، و اگر آنها متفاوت باشند، خروجی مقایسه مشخص می شود. اگر برابر باشند، دو عنصر بعدی مقایسه می شوند، و همینطور ادامه پیدا می کند تا یکی از دنباله ها به اتمام برسد.
اگر دو عنصری که می خواهند مقایسه شوند، خودشان دنباله هایی از نوع مشابه باشند، مقایسه واژه به واژه به صورت بازگشتی انجام می شود. اگر تمامی عناصر دو دنباله مقایسه شده برابر باشند، دنباله ها برابر تلقی می شوند. اگر یک دنباله زیر دنباله اولیه دیگری باشد، دنباله کوتاه تر کوچکتر است. مرتب سازی واژگان برای رشته ها، از Unicode code point number برای مرتب سازی کاراکتر های تکی استفاده می کند. تعدادی مثال از مقایسه دنباله ها از نوع مشابه ارائه شده است:
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
توجه داشته باشید که مقایسه اشیا از انواع مختلف با علامت < یا > مجاز است، زیرا متدهای مقایسه مناسب برای اشیا فراهم شده است. برای مثال، انواع عددی مختلط مطابق با مقدار عددی خود مقایسه می شوند، بنابراین 0 برابر است با 0.0 . در غیر این صورت، مفسر به جای ارائه یک مرتب سازی دلخواه، خطای TypeError را می دهد.
توجه !
ممکن است برخی زبان ها شی تغییر یافته را باز گردانند، که زنجیره متدها را امکان پذیر می سازد مانند
d->insert("a")->remove("b")->sort();
اگر از مفسر پایتون خارج شوید و سپس مجددا وارد شوید، چیزهایی که تعریف کرده اید مانند توابع و متغیرها از بین می روند. بنابراین، اگر می خواهید یک برنامه بلندتر بنویسید، بهتر است از یک ویرایشگر متن برای آماده سازی ورودی مفسر استفاده کنید، و با آن فایل به عنوان ورودی، برنامه را اجرا کنید.
این عمل با عنوان script شناخته شده است. هرچه برنامه شما بزرگتر می شود، ممکن است بخواهید برای نگهداری ساده تر، برنامه را به چندین فایل تقسیم کنید. همچنین ممکن است بخواهید از یک تابع دم دستی که در چندین برنامه نوشته اید، بدون تکرار تعریف آن در هر برنامه، استفاده کنید.
برای پشتیبانی از این، پایتون روشی برای قرارگیری تعاریف درون یک فایل و استفاده از آنها در یک کد (script) یا یک نمونه مفسر تعاملی دارد. چنین فایلی ماژول نام دارد. تعاریف از یک ماژول می توانند به ماژول های دیگر و یا ماژول اصلی وارد شوند (مجموعه متغیرهایی که در یک کد، اجرا شده در بالاترین سطح و مود ماشین حساب، به آن دسترسی دارید).
یک ماژول فایلی است که شامل تعاریف و عبارات پایتون است. نام فایل، نام ماژول است که دارای پسوند .py است. درون یک ماژول، نام ماژول (به عنوان یک رشته) به عنوان مقدار متغیر سراسری __name__ در دسترس است. برای مثال، از ویرایشگر متن مورد علاقه خود برای ساخت فایل fibo.py در دایرکتوری فعلی با محتوای زیر استفاده کنید.
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
حال وارد مفسر پایتون شوید و با استفاده از دستور زیر این ماژول را وارد کنید.
>>> import fibo
این عمل نام توابع تعریف شده در fibo را مستقیما در جدول نماد فعلی وارد نمی کند. فقط نام ماژول fibo را آنجا وارد می کند. با استفاده از نام ماژول می توانید به توابع دسترسی پیدا کنید.
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
اگر قصد استفاده از یک تابع را دارید، اغلب می توانید آن را به یک نام محلی تخصیص دهید.
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
یک ماژول می تواند در بردارنده عبارات قابل اجرا و همچنین تعاریف تابع باشد. هدف از این عبارات این است که آغاز گر ماژول باشند. این عبارات تنها در مرتبه اول که نام ماژول در عبارت واردات (import) دیده شود، اجرا می شوند. 1(همچنین اگر فایل به عنوان یک script اجرا شود، آنها هم اجرا می شوند.)
هر ماژول جدول نماد خصوصی خود را دارد، که به عنوان جدول نماد سراسری توسط تمامی توابع تعریف شده در ماژول استفاده می شود. بنابراین، نویسنده ماژول می تواند بدون نگرانی از درگیری تصادفی با متغیرهای سراسری کاربر، از متغیر های سراسری درون ماژول استفاده کند. از طرف دیگر، اگر بدانید چه کاری می کنید، می توانید به متغیرهای سراسری یک ماژول، با همان شیوه نوشتار استفاده شده برای ارجاع به توابع آن ، دسترسی داشته باشید
modname.itemname
ماژول ها می توانند ماژول های دیگر را وارد کنند (import). مرسوم است (و اما نه ضروری) که تمامی عبارات import در ابتدای ماژول (یا script) قرار گیرند. نام ماژول های وارد شده، در جدول نماد سراسری ماژول وارد کننده قرار می گیرد. یک نوع عبارت import وجود دارد که نام ها را از یک ماژول مستقیما به درون جدول نماد ماژول وارد کننده، وارد می کند. برای مثال:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
این کد، نام ماژولی که واردات از آن به جدول نماد محلی رفته است را معرفی نمی کند (بنابراین در مثال، fibo تعریف نشده است). حتی یک نوع import وجود دارد که تمامی نام های تعریف شده در یک ماژول را وارد میکند.
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
این کد تمامی نام ها به جز آنهایی که با_ شروع می شوند را وارد می کند. در بیشتر مواقع، برنامه نویسان پایتون از این قابلیت استفاده نمی کنند، زیرا این روش مجموعه ای از نام های نا شناخته را به مفسر معرفی و احتمالا برخی از چیزهایی که تاکنون تعریف کرده اید را پنهان می کند. توجه داشته باشید که به طور کلی عمل وارد کردن* از یک ماژول یا پکیج نا خوشایند است، زیرا اغلب باعث نا خوانایی کد می شود. هرچند در دوره های تعاملی استفاده از آن برای صرفه جویی در نوشتن بلا مانع است. اگر پس از نام ماژول، as وجود داشته باشد، نام قرار گرفته پس از as مستقیما محدود به ماژول وارد شده است.
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
این کد به همان صورتی که import fibo ماژول را وارد می کند، به صورت قابل اجرا ماژول را وارد می کند و تنها یک تفاوت دارد و آن اینکه به عنوان fib در دسترس است. همچنین در زمان استفاده از from میتوان با اثرات مشابه از آن استفاده کرد.
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
توجه !
به دلایل بهره وری، در هر دوره تفسیر، هر ماژول فقط یک بار وارد می شود. بنابراین، اگر ماژول های خود را تغییر دهید، باید مفسر را دوباره شروع کنید. یا اگر تنها یک ماژول است که می خواهید به صورت تعاملی آن را تست کنید، از importlib.reload() استفاده کنید. برای مثال
import importlib; importlib.reload(modulename)
هنگامی که یک ماژول پایتون را با دستور زیر اجرا می کنید:
python fibo.py <arguments>
</arguments>
کد درون ماژول اجرا خواهد شد، گویی که آن را وارد (import) کرده باشید، اما __name__ به "__main__" تغییر می یابد. این به این معناست که با اضافه کردن این کد به انتهای ماژول خود:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
میتوانید فایل را به صورت یک script ، همانند یک ماژول قابل وارد شدن(importable)، قابل استفاده کنید. زیرا کدی که خطوط دستور را پارس می کند(pars) ، تنها در صورتی که ماژول به عنوان فایل اصلی (main) اجرا شود، کار می کند.
$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34
اگر ماژول وارد شود، کد اجرا نمی شود:
>>> import fibo
>>>
معمولا از این قابلیت یا برای فراهم آوردن یک واسط کاربر مناسب برای ماژول، یا برای اهداف تست و ارزیابی استفاده می شود (اجرای ماژول به عنوان یک script ، یک مجموعه تست را اجرا می کند).
زمانی که یک ماژول با نام spam وارد شده باشد، در ابتدا مفسر به دنبال یک ماژول داخلی به این نام می گردد.
. سپس در صورتی که آن را پیدا نکند، به دنبال یک فایل با نام spam.py در لیستی از دایرکتوری های داده شده توسط متغیر sys.path می گردد.sys.path از مکان های زیر مقدار دهی اولیه می شود.
1- دایرکتوری شامل script ورودی (یا دایرکتوری فعلی در صورتی که هیچ فایلی مشخص نشده باشد).
2- در PYTHONPATH (لیستی از نام دایرکتوری ها، با نحوه نگارش مشابه متغیر پوسته path).
3- پیش فرض وابسته به نصب. نکته: در سیستم های فایل که از symlinks پشتیبانی می کنند، دایرکتوری شامل script ورودی پس از پیروی از symlinks محاسبه می شود. به عبارت دیگر، دایرکتوری شامل symlinks به مسیر جستجو ماژول اضافه نمی شود.
.پس از مقدار دهی اولیه، برنامه های پایتون می توانند sys.path را تغییر دهند. دایرکتوری شامل script ای که در حال اجراست، در آغاز مسیر جستجو، جلو تر از مسیر کتابخانه استاندارد قرار می گیرد. این به این معناست که script های داخل آن دایرکتوری، به جای ماژول های هم نام آن در دایرکتوری کتابخانه بارگذاری می شوند. این یک خطاست، مگر اینکه این جایگزینی مورد نظر شما باشد.
برای تسریع بارگذاری ماژول ها، پایتون نسخه کامپایل شده از هر یک از ماژول های درون دایرکتوری __pycache__ را تحت نام module.version.pyc می گیرد، جایی که نسخه، فرمت فایل کامپایل شده را رمزگشایی می کند و عموما شامل شماره نسخه پایتون است.
برای مثال، در CPython ارائه شده 3.3 ، نسخه کامپایل شده spam.py با عنوان __pycache__/spam.cpython-33.pyc ذخیره می شود. این اصول نامگذاری به ماژول های کامپایل شده از نسخه ها و انتشار های مختلف پایتون این امکان را می دهد تا در کنار هم قرار گیرند. پایتون تاریخ تغییر سورس (source) را با نسخه کامپایل شده مقایسه می کند تا ببیند آیا تاریخ آن گذشته و به کامپایل مجدد نیاز دارد یا خیر.
این یک روند کاملا خودکار است. همچنین، ماژول های کامپایل شده مستقل از پلتفرم(platform) هستند، بنابراین، یک کتابخانه مشابه را میتوان بین سیستم ها با معماری های مختلف به اشتراک گذاشت. تحت دو حالت پایتون cache را بررسی نمی کند.
برای پشتیبانی از توزیع غیر سورس (فقط کامپایل)، ماژول کامپایل شده باید در دایرکتوری سورس باشد، و هیچ ماژول سورسی نباید در آنجا باشد.
برخی نکات برای حرفه ای ها:
پایتون دارای یک کتابخانه از ماژول های استاندارد است که در یک سند مجزا به نام مرجع کتابخانه پایتون توصیف شده است (زین پس "مرجع کتابخانه").
برخی از ماژول ها درون مفسر ساخته شده اند. اینها دسترسی به عملیاتی که بخشی از هسته زبان نیستند اما با این حال داخلی (built in) هستند را با هدف بهره وری یا امکان دسترسی به اولیه های سیستم عامل مانند فراخوانی های سیستمی, فراهم می کند.
مجموعه چنین ماژول هایی یک گزینه پیکربندی است که به پلتفرم زیرساخت نیز وابسته است. برای مثال، ماژول winreg فقط برای سیستم های ویندوز فراهم شده است. یک ماژول خاص، sys ، که درون هر مفسر پایتون ساخته شده است، نیاز به توجه بیشتر دارد. متغیر های sys.ps1 و sys.ps2 رشته های استفاده شده در prompt اولیه و ثانویه را تعریف می کنند.
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
این دو متغیر تنها در صورتی که مفسر در مود تعاملی باشد، تعریف می شوند. متغیر sys.path لیستی از رشته هایی است که مسیر جستجوی مفسر برای ماژول ها را تعیین می کند. مقدار اولیه آن یک مسیر پیش فرض است که از متغیر محیطی PYTHONPATH ،یا از یک پیش فرض داخلی (built-in) در صورت عدم تنظیم PYTHONPATH ،دریافت شده است. می توانید با استفاده از عملیات استاندارد لیست آن را تغییر دهید.
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
از تابع داخلی dir() برای پیدا کردن نام هایی که یک ماژول تعریف می کند استفاده می شود. این تابع یک لیست مرتب شده از رشته ها را باز می گرداند.
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
'__package__', '__stderr__', '__stdin__', '__stdout__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
'_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
'call_tracing', 'callstats', 'copyright', 'displayhook',
'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
'thread_info', 'version', 'version_info', 'warnoptions']
بدون آرگومان ها، تابع dir() ، نام هایی که در حال حاضر تعریف کرده اید را لیست می کند.
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
توجه داشته باشید که همه نوع نام را لیست می کند. متغیر ها، ماژول ها، توابع و غیره.
تابع Dir() نام توابع و متغیر های داخلی را لیست نمی کند. اگر لیستی از آنها می خواهید، آنها در ماژول استاندارد builtins تعریف شده اند.
>>> dir(builtins)
['ArithmeticError', 'Asserti', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectiedError', 'Connecti',
'ConnectionRefusedError', 'ConnectiError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'Indentati', 'IndexError', 'InterruptedError',
'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'Permissi', 'ProcessLookupError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisi', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
'zip']
آموزش پایتون ادامه دارد