آموزش برنامه نویسی

به روز ترین مطالب آموزشی و متدلوژی های برنامه نویسی

آموزش برنامه نویسی

به روز ترین مطالب آموزشی و متدلوژی های برنامه نویسی

آموزشگاه تحلیل داده فعالیت رسمی خود را از سال 1380 در قالب آموزشگاه تخصصی نرم افزار آغاز نموده. این موسسه از همان ابتدای تأسیس با بهره مندی از استاید حرفه ای رشته های نرم افزار و بانک های اطلاعاتی ، فعالیت تخصصی خود را در زمینه آموزش برنامه نویسی و بانک های اطلاعاتی آغاز نمود و پس از گذشت اندک زمانی توانست در زمینه نرم افزار و شبکه بعنوان یکی از حرفه ای ترین موسسات ایران ظاهر شود. با توجه به اینکه مدیریت آموزشگاه شخصاً در رشته نرم افزار تحصیل کرده و سابقه طولانی در تحلیل و طراحی و پیاده سازی نرم افزار و بانک های اطلاعاتی دارند ، خط مشی کلی موسسه بر مبنای آموزش پایه ای ، کاربردی ، عملی و تخصصی نرم افزار بنا شده است.


آدرس : خیابان شریعتی بالاتر از ملک جنب بانک صادرات طبقه دوم واحد 7
همراه: 09123840871 تلفن: 88146323 - 88146330

۸ مطلب با کلمه‌ی کلیدی «فیلم آموزش پایتون» ثبت شده است

  • ۰
  • ۰
سلام دوستان...

 

با آموزش پایتون همراه ما باشید :

 

پایتون Python و دسترسی به دیتابیس MySQL
پایتون جهت دسترسی به دیتابیس از توابع کتابخانه ای DB-API استفاده کرده و interface هایی که برای اتصال به پایگاه داده و مدیریت داده های اپلیکیشن بایستی پیاده سازی شود، بر اساس همین استاندارد می باشد. در واقع بیشتر رابط های (interface) اتصال به دیتابیس از این استاندارد پیروی می کنند.
توسعه دهنده می تواند بر اساس نیاز اپلیکیشن خود، دیتابیس مناسب را انتخاب کند. توابع کتابخانه ای اتصال و استفاده از دیتابیس زبان پایتون (API) از database server های زیر پشتیبانی می کند:
  • GadFly
  • mSQL
  • MySQL
  • PostgreSQL
  • Microsoft SQL Server
  • Informix
  • Interbase
  • Oracle
  • Sybase
برای مشاهده لیست interface های اتصال به دیتابیس می توانید به این لینک مراجعه کنید: http://wiki.python.org/moin/DatabaseInterfaces. لازم به ذکر است که برای اتصال به هر دیتابیس مجزا و جهت دسترسی یا مدیریت داده های اپلیکیشن می بایست یک ماژول DB API جداگانه دانلود و نصب نمایید. به طور مثال، چنانچه توسعه دهنده می بایست علاوه بر MySQL به دیتابیس Oracle دسترسی پیدا کند، بدیهی است که باید ماژول های مجزا هریک را جداگانه از اینترنت بارگیری کرده و نصب نماید (ماژول های دیتابیس MySQL و Oracle).
ماژول DB API یک حداقل استاندارد برای مدیریت دیتابیس با استفاده از ساختار و دستور نحوی زبان برنامه نویسی پایتون در اختیار توسعه دهنده قرار می دهد. استفاده از این مجموعه توابع کتابخانه ای یا API مراحل زیر را شامل می شود:
  • وارد کردن ماژول این مجموعه توابع کتابخانه ای با استفاده از دستور import
  • برقراری اتصال به دیتابیس
  • صدور و فراخوانی دستورات و توابع (Store procedure) مورد نیاز SQL
  • بستن و قطع اتصال به دیتابیس
در آموزش حاضر تمامی این مباحث را با دیتابیس رابطه ای MySQL مدیریت می کنیم. به همین جهت ماژول MySQLdb را بارگیری نموده و نصب می کنیم.

 

آموزش پایتون : ماژول MySQLdb
ماژول MySQLdb یک رابط یا interface برای اتصال به سرویس دهنده دیتابیس MySQL (MySQL Database server) با زبان برنامه نویسی پایتون است که توسعه دهنده می بایست برای دسترسی و مدیریت داده های اپلیکیشن آن را پیاده سازی کند. این اینترفیس ویرایش 2.0 Database API پایتون را پیاده سازی کرده و بر پایه ی MySQL C API ساخته شده است.

 

نصب MySQLdb
جهت استفاده از توابع MySQLdb لازم است ماژول آن را بر روی دستگاه خود نصب نمایید. کافی است دستورات زیر را در اسکریپت پایتون لحاظ کرده و آن ها را اجرا نمایید:
#!/usr/bin/python
import MySQLdb
کد فوق یک پیغام خطا مبنی بر اینکه ماژول MySQLdb نصب نشده است تولید می کند:
Traceback (most recent call last):
File "test.py", line 3, in <module>
import MySQLdb
ImportError: No module named MySQLdb
</module>
به منظور نصب ماژول MySQLdb، کافی است دستورات زیر را تایپ نمایید:
For Ubuntu, use the following command -
$ sudo apt-get install python-pip python-dev libmysqlclient-dev
For Fedora, use the following command -
$ sudo dnf install python python-devel mysql-devel redhat-rpm-config gcc
For Python command prompt, use the following command -
pip install MySQL-python
نکته:
لازم است جهت نصب ماژول فوق، root privilege (مجوز در سطح دسترسی به فایل های ریشه) داشته باشید.

 

پیاده سازی اتصال به دیتابیس (Database connection) در آموزش پایتون
پیش از اتصال به دیتابیس MySQL، لازم است اقدامات زیر را کامل انجام داده باشید:
  • یک دیتابیس به نام TESTDB ایجاد نموده اید.
  • یک جدول به نام EMPLOYEE در دیتابیس مزبور تعریف کرده اید.
  • جدول مورد نظر فیلدهایی به نام FIRST_NAME، LAST_NAME، AGE، SEX و INCOME را دربرمی گیرد.
  • جهت دسترسی به دیتابیس User ID (شناسه ی کاربری) را بر روی "testuser" و گذرواژه را بر روی "test123" تنظیم کرده اید.
  • ماژول MySQLdb به طور کامل بر روی دستگاه مورد نظر نصب شده است.
  • با مفاهیم پایه و ابتدایی دیتابیس MySQL آشنایی کافی داشته باشید.

 

ماژول
ذیل مثالی را مشاهده می کنید که در آن توسعه دهنده با زبان پایتون به دیتابیس رابطه ای MySQL به نام "TESTDB" متصل می شود.
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# execute SQL query using execute() method.
cursor.execute("SELECT VERSION()")
# Fetch a single row using fetchone() method.
data = cursor.fetchone()
print "Database version : %s " % data
# disconnect from server
db.close()
خروجی اسکریپت فوق در دستگاه مبتنی بر Linux به صورت زیر می باشد.
Database version : 5.0.45
زمانی که اتصال به دیتابیس یا منبع داده ای مورد نظر با موفقیت انجام می شود، یک آبجکت Connection در خروجی بازگردانی شده و متعاقبا داخل آبجکت db جهت استفاده در آینده ذخیره می گردد. در غیر این صورت مقدار db برابر None قرار داده خواهد شد. آبجکت db سپس جهت اعلان و آماده سازی آبجکت cursor استفاده می شود. حال به منظور اجرای دستورهای درخواست داده و پرس و جو از دیتابیس، متد execute() بر روی آبجکت cursor فراخوانی می شود. در پایان، پیش از خروج از دیتابیس، اتصال به دیتابیس قطع شده و منابع مورد استفاده آزاد می شوند.

 

ایجاد جدول دیتابیس در آموزش پایتون
پس از اینکه اتصال به دیتابیس برقرار شد، توسعه دهنده می تواند اقدام به ساخت جدول و درج سطر در جداول دیتابیس نماید. برای این منظور لازم است متد execute را بر روی آبجکت cursor صدا بزند.
مثال
در زیر یک جدول به نام EMPLOYEE ایجاد می کنیم:
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Drop table if it already exist using execute() method.
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
# Create table as per requirement
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
# disconnect from server
db.close()

 

عملیات INSERT
این عملیات زمانی اجرا می شود که توسعه دهنده بخواهد سطر و رکورد جدید در جدول دیتابیس جاری درج نماید.
مثال
مثال زیر دستور INSERT زبان SQL را برای ایجاد رکورد جدید در جدول EMPLOYEE اجرا می کند:
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
# disconnect from server
db.close()
مثال فوق را می توان جهت تولید Query های SQL به صورت dynamic (در زمان اجرا) به صورت زیر نوشت:
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ('%s', '%s', '%d', '%c', '%d' )" % \
('Mac', 'Mohan', 20, 'M', 2000)
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
# disconnect from server
db.close()
مثال
تکه کد زیر روش دیگری از درج داده در سطر است که در آن شما می توانید پارامترها را به صورت مستقیم به متد execute ارسال کنید:
..................................
user_id = "test123"
password = "password"
con.execute('insert into Login values("%s", "%s")' % \
(user_id, password))
..................................

 

عملیات خواندن داده ها (READ)
عملیات READ منحصرا اطلاعات مفیدی را از دیتابیس واکشی می کند.
پس از برقرار اتصال به دیتابیس، می توان از آن جهت درخواست داده های مورد نظر Query گرفت. دو متد fetchone() و fetchall() نیز برای همین منظور تعبیه شده اند.
متد fetchone(): این متد همان طور که از اسم آن پیدا است، تنها یک رکورد یا سطر را در خروجی برمی گرداند. در واقع متد حاضر سطر بعدی از میان مجموعه سطرهای داده (result set خروجی کوئری) را بازگردانی می نماید. زمانی که توسعه دهنده با استفاده از cursor از دیتابیس کوئری می گیرد، خروجی یک آبجکت result set (مجموعه سطرهای داده) می باشد.
متد fetchall(): متد جاری قادر است همزمان چندین مقدار را ازدیتابیس واکشی کند. این متد تمامی سطرهای موجود در مجموعه سطرهای داده یا آبجکت result set را بازیابی می کند. اگر برخی از سطرها قبلا از دیتابیس استخراج شده باشد، در آن صورت باقی سطرها از آبجکت result set واکشی می شود.
متد rowcount: این المان یک attribute فقط خواندنی (read-only) است و تعدد سطرهایی که تحت تاثیر متد execute() قرار گرفتند را بازمی گرداند.
مثال
رویه procedure زیر تمامی سطرهای موجود در دیتابیس را از جدول EMPLOYEE که مقدار فیلد income آن بیشتر از 1000 می باشد را به عنوان خروجی کوئری بازمی گرداند:
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > '%d'" % (1000)
try:
# Execute the SQL command
cursor.execute(sql)
# Fetch all the rows in a list of lists.
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# Now print fetched result
print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \
(fname, lname, age, sex, income )
except:
print "Error: unable to fecth data"
# disconnect from server
db.close()
خروجی زیر را برمی گرداند:
fname=Mac, lname=Mohan, age=20, sex=M, income=2000

 

عملیات UPDATE و بروز رسانی داده ها
زمانی که عملیات UPDATE بر روی دیتابیس اجرا می شود، یک یا چندین سطر موجود در این دیتابیس با داده های جدید بروز رسانی می شوند.
رویه procedure و قطعه کدی که در زیر مشاهده می کنید، تمامی رکوردهایی که مقدار فیلد SEX آن ها 'M' می باشد را بروز رسانی می کند.در مثال جاری، مقدار فیلد AGE تمامی مردها را به میزان یک سال افزایش می دهیم.
مثال
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to UPDATE required records
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1
WHERE SEX = '%c'" % ('M')
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
# disconnect from server
db.close()

 

عملیات DELETE و حذف رکورد از دیتابیس
عملیات DELETE زمانی استفاده می شود که لازم باشد یک یا چند رکورد از دیتابیس مورد نظر پاک شوند. کد حاضر تمامی رکوردهای جدول EMPLOYEE که مقدار فیلد AGE آن ها بیش از 20 می باشد را حذف می نماید:
مثال
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to DELETE required records
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
# disconnect from server
db.close()

 

اجرای تراکنش بر روی دیتابیس (Transactions)
تراکنش یک مکانیزم است که دیتابیس را از یک وضعیت پایدار به وضعیت سالم و پایدار دیگر انتقال می دهد. تراکنش مجموعه ای از دستورها است که یا همه ی آن ها با موفقیت اجرا می شوند یا هیچکدام انجام نمی شوند.
تراکنش دارای چهار ویژگی معروف می باشد:
(اصل یا همه یا هیچ) Atomicity : تراکنش یا کاملا و به صورت یک پکیج اجرا می شود یا هیچ اتفاقی نمی افتد.
(اصل یکپارچگی و پایداری) Consistency: یک تراکنش باید پایگاه داده را از وضعیت پایدار و مشخص به وضعیت سالم، مشخص و پایدار دیگری انتقال دهد.
(اصل انزوا) Isolation: اطمینان حاصل می کند که تراکنش هایی که به طور همزمان اجرا می شوند، بر روی یکدیگر و سلامت دیتابیس اثری نمی گذارد، گویا هر یک در انزوا و به طور جداگانه اجرا می شوند.
(اصل پایایی و ماندگاری) Durability : زمانی که یک تراکنش به صورت نهایی ثبت و به اجرا رسید (commit)، اثرشان ماندگار و پایا خواهد بود، حتی اگر سیستم دچار خرابی ناگهانی شود.
مثال
از قبل حتما با نحوه ی پیاده سازی تراکنش آشنایی دارید. در زیر مثالی مشابه را می بینید:
# Prepare SQL query to DELETE required records
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
عملیات Commit و ثبت نهایی
کمیت Commit عملیاتی است که به دیتابیس اعلان می کند که باید تمامی تغییرات خود را به صورت نهایی ثبت کرده و پس از انجام آن دیگر امکان بازگشت به وضعیت قبلی وجود ندارد.
در زیر تکه کد ساده ای را مشاهده می کنید که متد commit() را بر روی آبجکت db صدا می زند.
db.commit()

 

عملیات ROLLBACK و بازگشت به وضعیت قبلی
اگر از تغییرات ثبت شده رضایت کامل ندارید، می توانید دیتابیس را به وضعیت قبل از انجام تراکنش بازگردانید. برای این منظور کافی است متد rollback() را بر روی آبجکت db فراخوانی نمایید.
db.rollback()

 

قطع اتصال به دیتابیس (متد close())
جهت بستن اتصال به دیتابیس کافی است متد close() را به صورت زیر فراخوانی نمایید:
db.close()
اگر اتصال به دیتابیس با فراخوانی متد close() بسته شود، در آن صورت تمامی تراکنش های انجام نشده به صورت نهایی، توسط DB به وضعیت قبلی بازگردانی می شوند.

 

مدیریت خطاها
خطاها بر اثر عوامل مختلفی رخ می دهند. برخی از خطاها بر اثر خطا گرامری و اشکال در سینتکس دستور SQL اجرا شده، رخ می دهند. برخی دیگر بر اثر عدم موفقیت در اتصال (connection failure) و برخی هم به دلیل فراخوانی متد fetch بر روی دستوری که قبلا یا کاملا انجام شده و یا لغو گردیده، اتفاق می افتند.
با DB API تعدادی خطا اعلان می کند که باید در هر ماژولی تعریف شده باشد. این خطاها (exceptions) در جدول زیر لیست شده اند:
 
اسکریپت های پایتون اپلیکیشن شما می بایست تمامی این خطاها را مدیریت کند. اما لازم است قبل از بکار بردن هر کدام از این exception ها اطمینان حاصل نمایید که MySQLdb امکان پشتیبانی از آن ها را دارد.
آموزش پایتون ادامه دارد.
  • افشین رفوآ
  • ۰
  • ۰
سلام دوستان...
با آموزش پایتون همراه ما باشید :

 

ماژول به شما این امکان را می دهد که کدهای خود را در پایتون سازمان دهی کنید. گروه بندی کدهای مرتبط با هم در یک ماژول، خوانایی کد و قابلیت استفاده از آن را بهبود می بخشد. ماژول یک شی است که دارای متغیرهای عضو (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 *
دستور یاد شده، روشی آسان برای وارد کردن تمامی آیتم های مورد نظر از یک ماژول در فضای نام جاری می باشد. با این حال توصیه می شود از این دستور فقط مواقع ضروری استفاده کنید.

 

مکان یابی ماژول
به هنگام وارد کردن یک ماژول، مفسر زبان پایتون به ترتیب شرح داده شده در زیر به دنبال ماژول مورد نظر می گردد.
  1. پوشه ی جاری.
  2. در صورت نیافتن ماژول، پایتون هر پوشه (directory) را در shell variableکه PYTHONPATH نام دارد جستجو می کند.
  3. در صورت موفق نبودن دو روش ذکر شده، پایتون مسیر پیش فرض را سرچ می کند. در محیط 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"
به طور مشابه، دو فایل دیگر داریم که با همان اسم دربردارنده ی توابع متفاوتی هستند.
  1. فایل Phone/Isdn.py حاوی تابع Isdn()
  2. فایل 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
 
 
 
آموزش پایتون ادامه دارد
  • افشین رفوآ
  • ۰
  • ۰

سلام دوستان...

با آموزش پایتون همراه ما باشید :

قسمت اول آموزش Python

 

آموزش توابع در پایتون

تابع یک قطعه کد سازمان دهی شده است که می توان آن را بارها فراخوانی کرده و مورد استفاده قرار داد. تابع به منظور اجرای یک عملیات خاص بکار می رود. توابع modularity (قابلیت تفکیک مولفه های سیستم و ادغام مجدد آن ها؛ در واقع modularity معماری نرم افزار را به کامپوننت هایی تقسیم می کند که پیاده سازی و نگهداشت آن را آسان می سازد) برنامه و قابلیت استفاده ی مجدد آن را بالا می برد. همان طور که می دانید، پایتون توابع درون ساخته ی متعددی همچون print() ارائه می دهد، با این حال کاربر می تواند توابع خود را تعریف کند که به آن توابع user-defined یا توابع کاربر می گویند.

 

تعریف تابع

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

  1. قطعه کد تابع باید با کلیدواژه ی def آغاز شود. به دنبال آن اسم تابع و پرانتز درج می شود ( () ).

  2. پارامترهای ورودی یا آرگومان ها باید داخل پرانتز قرار داده شوند.

  3. اولین دستور تابع می تواند یک دستور اختیاری باشد - function_docstring.

  4. قطعه کد داخل ساختمان یا بدنه ی تابع با دو نقطه آغاز می شود، سپس دستوراتی که زیر آن قرار می گیرند، همگی توگذاشته می شوند.

  5. دستور return اجرای تابع را متوقف کرده نتیجه را برمی گرداند (جمع بندی یک سری عملیات و یا کارهایی رو نمایش می دهد) و در صورت نیاز یک عبارت را به فراخواننده پاس می دهد. دستور return None نیز یعنی هیچ مقداری را به عنوان خروجی برنگرداند.

نحوه ی نگارش (syntax):

def functionname( parameters ):

"function_docstring"

function_suite

return [expression]

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

 

مثال

تابع زیر یک رشته به عنوان ورودی پذیرفته و آن را چاپ می کند.

def printme( str ):

"This prints a passed string into this function"

print str

return

 

آموزش پایتون : فراخوانی تابع

با تعریف تابع فقط یک اسم به آن تخصیص می یابد، سپس پارامترهای آن مشخص شده و ساختمان کد ایجاد می شود. پس از اینکه ساختمان تابع ایجاد می شود، می توانید آن را از تابع دیگر صدا بزنید یا آن را مسقیم از پنجره ی prompt پایتون فراخوانی کنید. مثال زیر تابع printme() را صدا می زند:

#!/usr/bin/python

# Function definition is here

def printme( str ):

"This prints a passed string into this function"

print str

return;

# Now you can call printme function

printme("I'm first call to user defined function!")

printme("Again second call to the same function")

نتیجه ی زیر حاصل می گردد:

I'm first call to user defined function!

Again second call to the same function

 

ارسال پارامتر با reference در برابر ارسال با مقدار

تمامی پارامترها (آرگومان ها) در زبان پایتون با reference پاس داده می شوند، بدین معنی که اگر آنچه یک پارامتر به آن اشاره دارد را در تابع تغییر دهید، تغییر در تابع فراخواننده نیز منعکس می شود.

#!/usr/bin/python

# Function definition is here

def changeme( mylist ):

"This changes a passed list into this function"

mylist.append([1,2,3,4]);

print "Values inside the function: ", mylist

return

# Now you can call changeme function

mylist = [10,20,30];

changeme( mylist );

print "Values outside the function: ", mylist

در اینجا reference به شی ارسالی حفظ شده و مقادیر جدید را به همان شی الصاق می کنیم. نتیجه:

Values inside the function: [10, 20, 30, [1, 2, 3, 4]]

Values outside the function: [10, 20, 30, [1, 2, 3, 4]]

یک مثال دیگر را در زیر مشاهده می کنید که آرگومان با reference ارسال شده و reference مورد نظر در تابع فراخوانده شده، بازنویسی (overwrite) شده است.

#!/usr/bin/python

# Function definition is here

def changeme( mylist ):

"This changes a passed list into this function"

mylist = [1,2,3,4]; # This would assig new reference in mylist

print "Values inside the function: ", mylist

return

# Now you can call changeme function

mylist = [10,20,30];

changeme( mylist );

print "Values outside the function: ", mylist

پارامتر mylist، نسبت به تابع changeme محلی (local) می باشد. ویرایش پارامتر مزبور در تابع موردنظر هیچ تاثیری بر روی mylist نمی گذارد. درواقع تابع هیچ کار خاصی انجام نمی دهد، نتیجه ای که از آن حاصل می گردد به شرح زیر می باشد:

Values inside the function: [1, 2, 3, 4]

Values outside the function: [10, 20, 30]

 

آرگومان های تابع

می توان یک تابع را به وسیله ی نوع آرگومان های لیست شده در زیر، فراخوانی کنید:

  1. آرگومان های الزامی

  2. آرگومان های Keyword

  3. آرگومان های پیش فرض

  4. آرگومان های با طول متغیر (Variable-length)

 

آرگومان های الزامی

آرگومان های الزامی، آرگومان هایی هستند که به ترتیب (تعریف شده) به تابع مورد نظر پاس داده می شوند. در اینجا، تعداد آرگومان هایی که در فراخوانی تابع مشخص می شود باید با تعریف تابع منطبق باشد. برای فراخوانی تابع printme()، می بایست یک آرگومان به آن ارسال کنید، در غیر این صورت خطای نحوی (syntax error) می دهد:

#!/usr/bin/python

# Function definition is here

def printme( str ):

"This prints a passed string into this function"

print str

return;

# Now you can call printme function

printme()

 

آرگومان های keyword

آرگومان های keyword در فراخوانی توابع مورد استفاده قرار می گیرد. هنگامی که از آرگومان های keyword در فراخوانی تابع استفاده می کنید، فراخواننده آرگومان ها را به وسیله ی اسم آن (پارامتر) شناسایی می کند. این کار به شما اجازه می دهد ترتیب آرگومان ها را تغییر دهید، زیرا که مفسر پایتون قادر است با استفاده از کلیدواژه ای ارائه شده، مقادیر را به پارامترها match (وصل) کند. می توانید تابع printme() را به ترتیب زیر فراخوانی کنید:

#!/usr/bin/python

# Function definition is here

def printme( str ):

"This prints a passed string into this function"

print str

return;

# Now you can call printme function

printme( str = "My string")

کد بالا پس از اجرا، نتیجه ی زیر را بدست می دهد:

My string

مثال زیر تصویر روشن تری از آن ارائه می دهد. توجه داشته باشید که ترتیب پارامترها اهمیتی ندارد.

#!/usr/bin/python

# Function definition is here

def printinfo( name, age ):

"This prints a passed info into this function"

print "Name: ", name

print "Age ", age

return;

# Now you can call printinfo function

printinfo( age=50, name="miki" )

خروجی:

Name: miki

Age 50

آرگومان پیش فرض آرگومانی است که در صورت مشخص نکردن مقداری در فراخوانی تابع برای آن، به صورت خودکار مقدار پیش فرض می پذیرد. نمونه ی زیر نشان می دهد که مقداری برای آرگومان age (در فراخوانی تابع) تعریف نشده، با این وجود تابع دوم مقدار 50 را برای آن چاپ می کند:

#!/usr/bin/python

# Function definition is here

def printinfo( name, age = 35 ):

"This prints a passed info into this function"

print "Name: ", name

print "Age ", age

return;

# Now you can call printinfo function

printinfo( age=50, name="miki" )

printinfo( name="miki" )

نتیجه:

Name: miki

Age 50

Name: miki

Age 35

 

دوره آموزش پایتون: آرگومان های با طول متغیر (Variable-length arguments)

گاهی لازم است یک تابع را با آرگومان های بیشتری نسبت به آنچه در زمان تعریف تابع مشخص کردید، پردازش و فراخوانی کنید. این دست از آرگومان ها در اصطلاح آرگومان های با طول متغیر (variable length) خوانده می شوند و برخلاف آرگومان های الزامی و پیش فرض، در تعریف تابع ذکر نمی شوند. نحوه ی نگارش:

def functionname([formal_args,] *var_args_tuple ):

"function_docstring"

function_suite

return [expression]

علامت (*) پیش از اسم متغیر (vartuple) که دارنده ی آرگومان های متغیر nonkeyword است، درج می شود. لازم به ذکر است که این tuple، چنانچه به هنگام فراخوانی تابع (function call) هیچ آرگومان اضافی مشخص نشود، تهی باقی می ماند. مثال:

#!/usr/bin/python

# Function definition is here

def printinfo( arg1, *vartuple ):

"This prints a variable passed arguments"

print "Output is: "

print arg1

for var in vartuple:

print var

return;

# Now you can call printinfo function

printinfo( 10 )

printinfo( 70, 60, 50 )

کد فوق نتیجه ی زیر را بدست می دهد:

Output is:

10

Output is:

70

60

50

 

توابع بی نام (Anonymous functions)

توابعی که به شیوه ی معمول و با درج کلیدواژه ی def تعریف نشده اند، توابع anonymous نام دارند. برای ایجاد توابع anonymous، بایستی از کلیدواژه ی lambda استفاده نمود.

  1. توابعی که به شکل lambda تعریف شده اند، قادراند چندین آرگومان به عنوان ورودی بپذیرند، اما فقط یک مقدار را در قالب عبارت به عنوان خروجی برمی گرداند. همچنین نمی توانند چندین دستور یا عبارت درخود داشته باشند.

  2. یک تابع anonymous نمی تواند به صورت مستقیم برای چاپ (print) فراخوانی شود، زیرا lambda به یک عبارت نیاز دارد.

  3. توابع lambda دارای فضای نامی محلی (local namespace) خود هستند و نمی توانند به متغیرهایی که در لیست پارامتر خود آورده نشده و نیز متغیرهایی که در فضای نامی سراسری هستند، دسترسی داشته باشند.

  4. اگرچه بنظر می رسد که lambda ها، نسخه ی تک خطی از یک تابع هستند، با این وجود معادل دستورات درون برنامه ای (in-line statement) در زبان های C و C++ محسوب نمی شوند که هدف از آن افزایش کارایی تابع به وسیله ی ارسال پشته ی تخصیص تابع هنگام فراخوانی است.

 

ساختار نگارشی

سینتکس توابع lambda همان طور که در نمونه ی زیر مشاهده می کنید، شامل تنها یک خط می باشد:

lambda [arg1 [,arg2,.....argn]]:expression

در زیر نحوه ی عملکرد تابعی که به صورت lambda تعریف شده باشد، را مشاهده می کنید:

#!/usr/bin/python

# Function definition is here

sum = lambda arg1, arg2: arg1 + arg2;

# Now you can call sum as a function

print "Value of total : ", sum( 10, 20 )

print "Value of total : ", sum( 20, 20 )

نتیجه:

Value of total : 30

Value of total : 40

 

دستور return

دستور [expression] return عملیات تابع را به پایان می رساند و خروجی آن را برمی گرداند و در صورت لزوم یک عبارت را به فراخواننده ارسال می نماید. دستور return ای که جلوی آن هیچ آرگومانی درج نشده باشد برابر با return none می باشد. مثال های بالا هیچ مقداری را برنمی گردانند. مثال زیر یک مقدار را از تابع به صورت زیر برمی گرداند:

#!/usr/bin/python

# Function definition is here

def sum( arg1, arg2 ):

# Add both the parameters and return them."

total = arg1 + arg2

print "Inside the function : ", total

return total;

# Now you can call sum function

total = sum( 10, 20 );

print "Outside the function : ", total

نتیجه ی آن را در زیر مشاهده می کنید:

Inside the function : 30

Outside the function : 30

 

حوزه ی دسترسی متغیر (variable scope)

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

  1. متغیرهای سراسری (global)

  2. متغیرهای محلی (local)

 

مقایسه ی متغیر سراسری با محلی

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

#!/usr/bin/python

total = 0; # This is global variable.

# Function definition is here

def sum( arg1, arg2 ):

# Add both the parameters and return them."

total = arg1 + arg2; # Here total is local variable.

print "Inside the function local total : ", total

return total;

# Now you can call sum function

sum( 10, 20 );

print "Outside the function global total : ", total

نتیجه:

Inside the function local total : 30

Outside the function global total : 0

آموزش پایتون ادامه دارد

  • افشین رفوآ
  • ۰
  • ۰
سلام دوستان...
در این قسمت از آموزش پایتون به مفهوم وراثت می پردازیم :
البته که یک ویژگی زبان به نام کلاس، بدون پشتیبانی از وراثت ارزش نخواهد داشت. نحوه نگارش برای تعریف یک کلاس مشتق شده به صورت زیر است:
class DerivedClassName(BaseClassName):
<statement-1>
.
.
.
<statement-n>
</statement-n></statement-1>
نام BaseClassName باید در حوزه‌ی در بر دارنده تعریف کلاس مشتق شده، تعریف شود. به جای نام یک کلاس پایه، سایر عبارات دلخواه نیز مجاز است. برای مثال زمانی که کلاس پایه در ماژول دیگری تعریف شده باشد، این می تواند مفید باشد.
class DerivedClassName(modname.BaseClassName):
آموزش پایتون : روند اجرای تعریف یک کلاس مشتق شده همانند کلاس پایه است. زمانی که شی کلاس ساخته شود، کلاس پایه به یاد می آید. از این برای بر طرف کردن ارجاع های ویژگی استفاده می شود. اگر یک ویژگی درخواست شده در کلاس موجود نباشد، روند جستجو به بررسی کلاس پایه می پردازد. در صورتی که خود کلاس پایه نیز از کلاس دیگری مشتق شده باشد، این قانون به صورت بازگشتی اعمال می شود.
هیچ چیز خاصی درباره نمونه گیری از کلاس های مشتق شده و جود ندارد: DerivedClassName() یک نمونه جدید از کلاس ایجاد می کند. ارجاع های متد به این صورت انجام می شوند: ویژگی کلاس مربوطه جستجو می شود، در صورت لزوم از زنجیره کلاس های پایه پایین می آید، و اگر این به یک شی تابع برسد (اگر این عملیات به نتیجه برسد)، مرجع متد معتبر است.
کلاس های مشتق شده ممکن است متدهای کلاس های پایه خود را تغییر دهند. زیرا متدها در زمان فراخوانی سایر متدهای یک شی مشابه، هیچ امتیاز خاصی ندارند. یک متد از یک کلاس پایه، که متد دیگری که در همان کلاس پایه تعریف شده است را فراخوانی کند، ممکن است به فراخوانی یک متد از یک کلاس مشتق شده که آن را تغییر داده است منجر شود. (برای برنامه نویسان C++: تمامی متدهای پایتون به طور موثری مجازی (virtual) هستند.)
متد تغییر دهنده در یک کلاس مشتق شده ممکن است در واقع به جای جایگزینی متد کلاس پایه هم نام، صرفا بخواهد آن را توسعه دهد. یک روش ساده برای فراخوانی مستقیم متد کلاس پایه وجود دارد: فقط BaseClassName.methodname(self, arguments) را صدا کنید. همچنین این گاهی برای مشتری ها نیز مفید است. (توجه داشته باشید این تنها در صورتی که کلاس پایه به عنوان BaseClassName در حوزه سراسری قابل دسترس باشد، کار می کند. )
پایتون دارای دو تابع داخلی است که با وراثت کار می کنند:
  • برای بررسی نوع یک نمونه از isinstance() استفاده کنید: تنها در صورتی که obj.__class__ ، int باشد یا کلاسی مشتق شده از int ، isinstance(obj, int)، True خواهد بود.
  • برای بررسی وراثت کلاس از issubclass() استفاده کنید:‌ issubclass(bool, int) ، True است زیرا bool زیر کلاس int است. اگر چه issubclass(float, int) ، False است زیرا float زیر کلاس int نیست.

 

وراثت چندگانه در آموزش پایتون
همچنین پایتون از گونه ای از وراثت چندگانه (multiple inheritance) پشتیبانی می کند. تعریف یک کلاس با چندین کلاس پایه به صورت زیر است:
    class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-n>
</statement-n></statement-1>
برای بیشتر مقاصد، در ساده ترین حالت، می توانید جستجو برای ویژگی های به ارث رسیده از یک کلاس والد را به صورت اول-عمق، چپ –به- راست، در نظر بگیرید که در یک کلاس مشابه که همپوشانی در سلسله مراتب وجود دارد دو بار جستجو نکنید. بنابراین، اگر یک ویژگی در DerivedClassName یافت نشود، در Base1 جستجو شده است، سپس (به صورت بازگشتی) در کلاس پایه Base1 جستجو شده است، و اگر در آنجا نیز یافت نشود، در Base2 جستجو می شود و این روند ادامه دارد.
در حقیقت قضیه کمی پیچیده تر از این است. ترتیب وضوح متد، برای پشتیبانی از فراخوانی های مشارکتی super() به صورت پویا تغییر می کند. این روند در سایر زبان های وراثت چندگانه با عنوان فراخوانی متد بعدی (call-next-method ) شناخته شده است و بسیار قدرتمند تر از فراخوانی super() موجود در زبان های تک وراثتی است.
از آنجایی که همه موارد وراثت چندگانه، یک یا چند رابطه لوزی گون (جایی که حد اقل یکی از کلاس های والد می تواند از طریق چندین مسیر از پایین ترین کلاس دسترس پذیر باشد). را ارائه می کنند، مرتب سازی پویا ضروری است . برای مثال، تمامی کلاس ها از object ارث می برند، بنابراین هر موردی از وراثت چندگانه، بیشتر از یک مسیر برای دستیابی به object را فراهم می کند. برای جلوگیری از دسترسی به کلاس های پایه، بیشتر از یک بار، الگوریتم پویا به گونه ای ترتیب جستجو را خطی می کند که ترتیب چپ به راست مشخص شده در هر کلاس، که هر والد را فقط یک بار صدا میزند، را حفظ کند، و این یکنواخت است (به این معنی که یک کلاس می تواند بدون اثر گذاری روی ترتیب حق تقدم والدین خود، زیر کلاس شود). همه این ویژگی ها با هم، طراحی کلاس های قابل اطمینان و قابل توسعه با وراثت چندگانه را امکان پذیر می کند.

 

آموزش متغیر های خصوصی (Private) در برنامه نویسی پایتون
متغیر های نمونه خصوصی که از جایی غیر از درون یک شی قابل دسترس نباشند، در پایتون وجود ندارد. اگر چه قراردادی وجود دارد که توسط اکثر کدهای پایتون رعایت می شود: نامی که بعد از خط زیرین بیاید، مانند (_spam) باید به عنوان یک بخش غیر عمومی از API در نظر گرفته شود( چه یک تابع باشد یا یک متد یا یک عضو داده). این باید به عنوان جزییات پیاده سازی در نظر گرفته شود و بدون اطلاع قبلی تغییر کند.
از آنجایی که یک کاربرد معتبر برای اعضای خصوصی کلاس وجود دارد( برای جلوگیری از درگیری نام ها با نام های تعریف شده توسط زیر کلاس ها)، یک پشتیبانی محدود به نام ‘تغییرات نام’ (name mangling) برای چنین مکانیزمی وجود دارد.
هر شناسه ای در قالب __spam (حد اقل دو خط زیرین در قبل، حداکثر یک خط زیرین در ادامه) از لحاظ نگارشی با _classname__spam جایگزین می شود، که classname نام کلاس جاری است که خط زیرین قبل از آن حذف شده است. این تغییرات تا زمانی که درون تعریف کلاس رخ دهند ، بدون توجه به مکان نوشته شدن شناسه انجام می شوند.
تغییرات نام برای امکان پذیر کردن تغییر متدها توسط زیر کلاس ها، بدون شکستن فراخوانی های متد درون-کلاسی مفید هستند. برای مثال:
def __init__(self, iterable):
self.items_list = []
self.__update(iterable)
 
def update(self, iterable):
for item in iterable:
self.items_list.append(item)
 
__update = update # private copy of original update() method
 
class MappingSubclass(Mapping):
 
def update(self, keys, values):
# provides new signature for update()
# but does not break __init__()
for item in zip(keys, values):
self.items_list.append(item)
مثال بالا حتی اگر MappingSubclass مجبور به معرفی شناسه __update باشد نیز کار می کند، زیرا به ترتیب با _Mapping__update در کلاس Mapping ، و _MappingSubclass__update در کلاس MappingSubclass جایگزین شده است.
توجه داشته باشید، قوانین تغییرات اکثرا برای جلوگیری از تصادفات طراحی شده اند اما همچنان احتمال دسترسی یا تغییر متغیری که خصوصی فرض می شود وجود دارد. در بعضی شرایط خاص مانند اشکال زدایی، این امر می تواند حتی مفید باشد.
توجه کنید، کد پاس داده شده به exec() یا eval() ، نام کلاس صدا زننده کلاس را به عنوان کلاس جاری در نظر نمی گیرد. این مشابه اثر عبارت global است، اثری که به همین ترتیب به کدی که با هم کامپایل (byte-compiled) شده اند محدود می شود. همین محدودیت روی getattr() ، setattr() و delattr() ، و نیز در زمان ارجاع مستقیم به __dict__ اعمال می شود.
 

 

آموزش odds و ends در برنامه نویسی پایتون
گاهی اوقات داشتن یک نوع داده، مشابه record در پاسکال یا struct در C می تواند مفید باشد تا تعدادی آیتم داده نام گذاری شده را با هم جمع کنیم. یک تعریف کلاس خالی در اینجا مناسب خواهد بود:
class Employee:
pass
 
john = Employee() # Create an empty employee record
 
# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
یک قطعه کد پایتون که انتظار یک نوع داده انتزاعی خاص را دارد، اغلب می تواند از یک کلاسی که به جای آن، متدهای آن نوع داده را تقلید می کند، عبور داده شود . برای مثال، اگر تابعی داشته باشید که برخی داده ها را از یک شی فایل فرمت(format) می کند، می توانید یک کلاس با متد های read() و readline() تعریف کنید که داده را از بافر رشته دریافت کند و آن را به عنوان یک آرگومان پاس دهد.
اشیای متد نمونه نیز دارای ویژگی هستند: m.__self__ شی نمونه با متد m() است، و m.__func__ شی تابع متناظر با متد است.
آموزش پایتون ادامه دارد
  • افشین رفوآ
  • ۰
  • ۰
سلام دوستان...
در این قسمت از آموزش پایتون نگاه اولیه به کلاس ها داریم :
کلاس ها مقدار کمی نحو(syntax) جدید را معرفی می کنند، از جمله سه نوع شی جدید و برخی مفاهیم(semantics) جدید.

 

آموزش نحوه تعریف کلاس در Python
ساده ترین حالت تعریف کلاس به صورت زیر است:
class ClassName:
<statement-1>
.
.
.
<statement-n>
</statement-n></statement-1>
 
تعاریف کلاس، مانند تعاریف تابع(عبارت def) باید پیش از اینکه اثری داشته باشند، اجرا شوند. (می توانید تعریف یک کلاس را در شاخه ای از یک عبارت if یا درون یک تابع قرار دهید.)
در عمل، عبارات درون تعریف یک کلاس، معمولا تعاریف تابع خواهند بود، اما عبارات دیگر نیز مجار هستند و گاهی مفید—بعدا به این موضوع خواهیم پرداخت. تعاریف تابع درون یک کلاس معمولا یک شکل عجیبی از لیست آرگومان ها دارند، که توسط قراردادهای فراخوانی متدها نوشته شده اند—دوباره می گویم، این موضع بعدا توضیح داده خواهد شد.
وقتی تعریف یک کلاس وارد شود، یک فضای نام جدیدی ساخته می شود و به عنوان حوزه محلی استفاده می شود—بنابراین، تمامی تخصیص ها به متغیر های محلی، به این فضای نام جدید می روند. به خصوص، تعاریف تابع، نام تابع جدید را در اینجا اتصال می دهند.
زمانی که تعریف یک کلاس به صورت نرمال قرار گیرد(از طریق پایان)، یک شی کلاس ساخته می شود. این اساسا یک بسته بندی حول محتویات فضای نامی است که توسط تعریف کلاس ایجاد شده است. در بخش بعدی مباحث بیشتری درباره اشیای کلاس فرا خواهیم گرفت. حوزه محلی اصلی ( حوزه ای که دقیقا قبل از تعریف کلاس وارد شده است) باز گردانده شده است، و شی کلاس، به نام کلاس که در سربرگ تعریف کلاس است، محدود شده است. (ClassName در مثال).

 

اشیای کلاس در آموزش پایتون

 

آموزش Class Objects در پایتون
اشیای کلاس از دو نوع عملیات پشتیبانی می کنند: ارجاع های ویژگی (attribute references) و نمونه گیری (instantiation).
ارجاع های ویژگی، از نحوه نگارش استاندارد مورد استفاده برای تمامی ارجاع های ویژگی در پایتون، استفاده می کنند: obj.name . تمامی نام های موجود در فضای نام کلاس، در زمان ساخت شی کلاس، نام های معتبر ویژگی هستند. بنابراین اگر تعریف کلاس به صورت زیر باشد:
class MyClass:
"""A simple example class"""
i = 12345
 
def f(self):
return 'hello world'
پس MyClass.i و MyClass.f ارجاع های ویژگی معتبر هستند، که به ترتیب یک عدد صحیح و یک شی تابع را باز می گردانند. همچنین می توان به ویژگی های کلاس مقداری را تخصیص داد، بنابراین می توانید مقدار MyClass.i را با تخصیص، تغییر دهید. __doc__ نیز یک ویژگی معتبر است، که docstring متعلق به کلاس "A simple example class" را باز می گرداند. نمونه گیری کلاس از نمادگذاری تابع استفاده می کند. فقط وانمود کنید که شی کلاس یک تابع بدون پارامتر است که یک نمونه جدید از کلاس را باز می گرداند. برای مثال(کلاس بالا را در نظر بگیرید):
x = MyClass()
عبارت بالا یک نمونه جدید از کلاس را ایجاد می کند و این شی را به متغیر محلی x تخصیص می دهد. عمل نمونه گیری (صدا زدن یک شی کلاس) یک شی خالی را ایجاد می کند. بسیاری از کلاس ها، تمایل به ایجاد اشیا با نمونه هایی که برای یک حالت اولیه خاص سفارشی شده باشند، دارند. بنابراین ممکن است یک کلاس یک متد خاص به نام __init__() را به صورت زیر تعریف کند:
def __init__(self):
self.data = []
زمانی که یک کلاس متد __init__() را تعریف می کند، نمونه گیری کلاس، به صورت خودکار __init__() را برای نمونه تازه ساخته شده کلاس فراخوانی می کند. بنابراین در این مثال، یک نمونه جدید و مقدار دهی اولیه شده توسط عبارت زیر قابل دستیابی است:
x = MyClass()
البته که متد __init__() میتواند برای انعطاف پذیری بیشتر دارای آرگومان باشد. در این صورت، آرگومان های داده شده به عملگر نمونه گیری کلاس، به __init__() پاس داده می شوند. برای مثال:
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

 

آموزش اشیای نمونه (instance objects) در Python
حال با اشیای نمونه چه کار می توان کرد؟ تنها عملیات قابل فهم توسط اشیای نمونه، ارجاع های ویژگی هستند. دو نوع نام ویژگی معتبر وجود دارد: ویژگی های داده (data attributes) و متدها.
ویژگی های داده” متناظر است با “متغیر های نمونه” در Smalltalk و "اعضای داده” در C++ . ویژگی های داده نیازی به اعلان شدن ندارند؛ آنها همانند متغیر های محلی، در اولین جایی که مقداری به آنها تخصیص یابد، به وجود می آیند. برای مثال، اگر x نمونه MyClass که در بالا ایجاد شد، باشد، قطعه کد زیر مقدار 16 را بدون برجای گذاشتن ردی چاپ خواهد کرد.
x.counter = 1
while x.counter < 10:
x.counter = x.counter * 2
print(x.counter)
del x.counter
نوع دیگری از ارجاع ویژگی نمونه (instance attribute reference)، متد است.
یک متد تابعی است که متعلق به یک شی است. ( در پایتون، واژه متد تنها مختص به نمونه های کلاس نیست: سایر انواع شی هم می توانند متد داشته باشند. برای مثال، اشیای لیست، متدهایی به نام های append ، insert ، remove ، sort و غیره دارند. اگر چه در مباحث بعدی منحصرا از واژه متد برای بیان متدهای اشیای نمونه کلاس استفاده می شود، مگر اینکه صریحا خلاف آن بیان شود.)
نام های معتبر متد مربوط به یک شی نمونه، به کلاس آن بستگی دارد. در تعریف، تمامی ویژگی های یک کلاس که اشیای تابع هستند، متدهای متناظر با نمونه های آن را تعریف می کنند. بنابراین در مثال ما، از آنجایی که MyClass.f یک تابع است، x.f یک ارجاع معتبر متد است. اما x.i (معتبر)نیست، زیرا MyClass.i (یک تابع) نیست. اما x.f چیزی مشابه MyClass.f نیست—این یک شی متد است، نه یک شی تابع.

 

اشیای متد (method objects) در آموزش پایتون
معمولا یک متد دقیقا پس از بسته شدن (bound)، فراخوانی می شود:
x.f()
در مثال MyClass ، رشته 'hello world' باز گردانده می شود. اگر چه، فراخوانی بلافاصله یک متد، ضروری نیست: x.f یک شی متد است، و می تواند در زمانی دیگر ذخیره و صدا زده شود. برای مثال:
xf = x.f
while True:
print(xf())
تا آخر زمان به چاپ hello world ادامه می دهد. زمانی که یک متد فراخوانی می شود، دقیقا چه اتفاقی می افتد؟ ممکن است متوجه شده باشید که x.f() در بالا بدون آرگومان فراخوانی شده است، هر چند که تعریف تابع برای f() یک آرگومان مشخص کرده است. چه اتفاقی برای آرگومان افتاد؟ زمانی که تابعی نیاز به یک آرگومان دارد و بدون آرگومان فراخوانی می شود، پایتون حتما استثنایی را اعلام می کند—حتی اگر آن آرگومان واقعا استفاده نشده باشد.
در واقع ممکن است پاسخ را حدس زده باشید: نکته خاص درباره متد ها این است که شی نمونه به عنوان اولین آرگومان تابع پاس داده می شود. در مثال ما، فراخوانی x.f() دقیقا برابر با فراخوانی MyClass.f(x) است. به طور کلی، فراخوانی یک متد با لیستی از n آرگومان، برابر است با فراخوانی تابع متناظر آن، با لیستی از آرگومان ها که به واسطه درج شی نمونه متد، قبل از اولین آرگومان ساخته شده است.
اگر همچنان متوجه نحوه عملکرد متدها نمی شوید، نگاهی به پیاده سازی احتمالا میتواند قضیه را روشن کند. زمانی که یک ویژگی غیر داده از یک نمونه، ارجاع یافته باشد، کلاس نمونه جستجو می شود. اگر نام، یک ویژگی کلاس معتبر که یک شی تابع است را نشان دهد، یک شی متد به واسطه جمع کردن(اشاره گر ها به) شی نمونه و شی تابع که با هم در یک شی abstract پیدا شده اند، ساخته میشود: این شی متد است. زمانی که شی متد به همراه لیستی از آرگومان ها فراخوانی شده باشد، یک لیست آرگومان جدید از شی نمونه و لیست آرگومان ها ساخته می شود، و شی تابع با لیست آرگومان جدید فراخوانی می شود.

 

آموزش متغیر های کلاس و نمونه در برنامه نویسی Python
به طور کلی، متغیر های نمونه برای داده هستند و برای هر نمونه یکتا هستند. متغیر های کلاس برای ویژگی ها و متدها هستند و بین همه نمونه های کلاس به اشتراک گذاشته می شوند.
class Dog:
 
kind = 'canine' # class variable shared by all instances
 
def __init__(self, name):
self.name = name # instance variable unique to each instance
 
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
'canine'
>>> e.kind # shared by all dogs
'canine'
>>> d.name # unique to d
'Fido'
>>> e.name # unique to e
'Buddy'
همانطور که در بخش سخنی درباره نام ها و اشیا بحث شد، داده های اشتراکی می توانند تاثیرات احتمالی شگفت انگیزی با اشیای تغییر پذیر درگیر مانند لیست ها و دیکشنری ها داشته باشند. برای مثال، لیست tricks در کد زیر نباید به عنوان متغیر کلاس استفاده شود زیرا تنها یک لیست توسط همه نمونه های Dog به اشتراک گذاشته می شود.
طراحی صحیح کلاس، باید به جای آن از یک متغیر نمونه استفاده کند.
    class Dog:
 
    def __init__(self, name):
        self.name = name
        self.tricks = []    # creates a new empty list for each dog
 
    def add_trick(self, trick):
        self.tricks.append(trick)
 
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']

 

آموزش (random remarks) در برنامه نویسی پایتون
اگر یک نام ویژگی(attribute name) مشابه هم در یک نمونه و هم در یک کلاس رخ دهد، سپس جستجوی ویژگی، نمونه را اولویت بندی می کند.
>>> class Warehouse:
purpose = 'storage'
region = 'west'
 
>>> w1 = Warehouse()
>>> print(w1.purpose, w1.region)
storage west
>>> w2 = Warehouse()
>>> w2.region = 'east'
>>> print(w2.purpose, w2.region)
storage east
ویژگی های داده همانطور که توسط کاربران معمولی (مشتری ها) یک شی ارجاع داده می شوند، ممکن است توسط متدها نیز ارجاع یابند. به بیان دیگر، کلاس ها برای پیاده سازی انواع داده انتزاعی خالص قابل استفاده نیستند. در حقیقت، هیچ چیزی در پایتون، اجبار به پنهان سازی داده را ممکن نمی کند—همه چیز بستگی به قرارداد دارد. ( از طرف دیگر، پیاده سازی پایتون، نوشته شده در C، می تواند به طور کامل جزییات پیاده سازی را پنهان کند و دسترسی به یک شی را در صورت نیاز کنترل کند. توسط ضمیمه های پایتون که به C نوشته شده است، می توان از این استفاده کرد. )
مشتری ها (Clients) باید با احتیاط از ویژگی های داده استفاده کنند—مشتری ها ممکن است ثابت های(invariants) نگهداری شده توسط متد ها را با مهر زدن روی ویژگی های داده آنها اشتباه بگیرند. توجه داشته باشید که ممکن است مشتری ها ویژگی های داده خود را بدون تاثیر گذاری روی اعتبار متدها، به یک شی نمونه اضافه کنند، البته تا زمانی که از ناسازگاری بین نام ها پرهیز شود—مجددا می گویم، قرارداد های نام گذاری می تواند مانع بسیاری از دردسرها در اینجا شود.
هیچ گونه اختصار نویسی برای ارجاع ویژگی های داده(یا سایر متدها) از درون متدها وجود ندارد. در واقع به نظر من این خوانایی متدها را افزایش می دهد: در نگاه کلی به یک متد، امکان اشتباه و سر در گمی بین متغیرهای محلی و متغیرهای نمونه به هیچ وجه وجود ندارد.
اغلب اولین آرگومان یک متد self نام دارد. این فقط یک قرارداد است. نام self مطلقا هیچ معنی خاصی برای پایتون ندارد. هر چند توجه داشته باشد که با رعایت نکردن قراردادها، ممکن است کد شما برای سایر برنامه نویسان پایتون از خوانایی کمتری برخوردار باشد. همچنین ممکن است یک برنامه مرورگر کلاس با تکیه بر چنین قراردادهای نوشته شود.
هر شی تابعی که یک ویژگی کلاس باشد، یک متدی را برای نمونه های آن کلاس تعریف می کند. ضروری نیست که تعریف تابع به صورت نوشتاری درون تعریف کلاس قرار گیرد (محصور باشد). تخصیص یک شی تابع به یک متغیر محلی درون کلاس نیز کفایت می کند. برای مثال:
# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)
class C:
    f = f1
    def g(self):
        return 'hello world'
    h = g
حال f,g و h همه ویژگی های کلاس c هستند که به اشیای تابع رجوع می کنند، و متعاقبا همه آنها متدهای نمونه های c هستند – h دقیقا برابر است با g. توجه داشته باشید که معمولا این عمل تنها برای سر در گم کردن خواننده برنامه انجام می شود.
ممکن است متدها با استفاده از ویژگی های متد آرگومان self، سایر متدها را فراخوانی کنند.
class Bag:
def __init__(self):
self.data = []
 
def add(self, x):
self.data.append(x)
 
def addtwice(self, x):
self.add(x)
self.add(x)
متدها ممکن است به همان شیوه مشابه ارجاع توابع معمولی، نام های سراسری را ارجاع دهند. حوزه سراسری مربوط به یک متد، ماژولی است که در بردارنده تعریف آن است. (یک کلاس هرگز به عنوان یک حوزه سراسری استفاده نمی شود.) درحالی که به ندرت به دلیل خوبی برای استفاده از داده سراسری در یک متد بر میخوریم، کاربرد های درست و قانونی بسیاری از حوزه سراسری وجود دارد: یک مورد این است که، توابع و ماژول های وارد شده به حوزه سراسری می توانند مانند توابع و کلاس های تعریف شده در آن، توسط متدها استفاده شوند. معمولا کلاسی که در بردارنده متد است، خود نیز درون حوزه سراسری تعریف شده است. در بخش بعد دلایل خوبی برای اینکه چرا یک متد ممکن است بخواهد به کلاس خود ارجاع دهد، را بیان می کنیم.
هر مقدار، یک شی است و بنابراین یک کلاس دارد(نوع آن نیز نامیده می شود) و به عنوان object.__class__ ذخیره می شود.
آموزش پایتون ادامه دارد
  • افشین رفوآ
  • ۰
  • ۰
سلام دوستان ...در قسمت قبل آموزش پایتون مفاهیم زیر را یاد دادیم
  • آموزش خواندن و نوشتن فایل در زبان برنامه نویسی پایتون
  • آموزش خطاها و استثناها در برنامه نویسی پایتون
  • آموزش مدیریت استثناها در آموزش پایتون
 
با ادامه آموزش پایتون همراه ما باشید.
 

 

آموزش اعلام استثناها در برنامه نویسی پایتون
عبارت raise به برنامه نویس این امکان را می دهد تا یک استثنای خاص را مجبور به رخ دادن کند. برای مثال:
>>> raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: HiThere
</module></stdin>
تنها آرگومان raise بیان می کند که استثنا اعلام شود. این یا باید یک نمونه استثنا (exception instance) باشد یا یک کلاس استثنا ( یک کلاس که از Exception مشتق شده باشد). اگر یک کلاس استثنا پاس شود، با فراخوانی سازنده آن بدون هیچ آرگومانی، به طور ضمنی نمونه گیری می شود.
raise ValueError  # shorthand for 'raise ValueError()'
اگر باید تعیین کنید که آیا یک استثنا اعلام شده اما قصد مدیریت آن را ندارید، حالت ساده تری از عبارت raise به شما این امکان را می دهد تا استثنا را دوباره اعلام کنید.
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere
</module></stdin>

 

آموزش استثناهای تعریف شده توسط کاربر در آموزش پایتون
برنامه ها ممکن است با ساخت یک کلاس جدید استثنا، خود برای استثناهای خود نام بگذارند
معمولا استثناها باید به طور مستقیم یا غیر مستقیم از کلاس Exception مشتق شوند.
کلاس های استثنا را میتوان به گونه ای تعریف کرد که کارهایی که هر کلاس دیگری انجام می دهد را بتوانند انجام دهند، اما معمولا آنها را ساده می سازند. این کلاس ها اغلب فقط تعدادی ویژگی ارائه می کنند که امکان استخراج اطلاعات درباره خطا توسط اداره کننده خطا (handler) را فراهم می کند.
در زمان ایجاد ماژولی که بتواند چندین خطای متمایز را اعلام کند، معمول است که یک کلاس پایه برای استثناهای تعریف شده توسط آن ماژول ایجاد کنند، و نیز زیر کلاسی برای ایجاد کلاس های استثنای خاص برای شرایط متفاوت خطا بسازند.
class Error(Exception):
"""Base class for exceptions in this module."""
pass
 
class InputError(Error):
"""Exception raised for errors in the input.
 
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
 
def __init__(self, expression, message):
self.expression = expression
self.message = message
 
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
 
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
 
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
اکثر استثناها، مشابه نامگذاری استثناهای استاندارد، با نام هایی که به “Error” ختم می شود تعریف می شوند. بسیاری از ماژول های استاندارد به منظور گزارش خطاهایی که ممکن است در توابعی که خود تعریف کرده اند رخ دهد، استثناهای خود را تعریف می کنند.

 

آموزش تعریف عملیات تمیزکاری در برنامه نویسی آموزش پایتون
عبارت try یک بخش اختیاری دیگری نیز دارد که وظیفه آن تعریف عملیات تمیزکاری (clean-up actions) است که تحت هر شرایطی باید اجرا شوند. برای مثال:
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
</module></stdin>
اگر یک بخش finally وجود داشته باشد، این بخش finally به عنوان اخرین وظیفه قبل از تکمیل شدن عبارت try اجرا خواهد شد. بخش finally ، چه عبارت try، استثنایی تولید کند یا نکند، اجرا می شود. نکات زیر موارد پیچیده تری از زمانی که استثنا رخ می دهد را بیان می کند.
  • اگر استثنایی در حین اجرای بخش try رخ دهد، استثنا ممکن است توسط بخش except اداره شود. اگر استثنا توسط بخش except اداره نشود، استثنا پس از اجرای بخش finally ، دوباره اعلام می شود.
  • یک استثنا می تواند در حین اجرای یک بخش except یا else رخ دهد. مجددا، استثنا پس از اجرای بخش finally ، دوباره اعلام می شود.
  • اگر عبارت try به یک عبارت break ، continue یا return برسد، بخش finally دقیقا قبل از اجرای عبارات break ، continue یا return اجرا می شود.
  • اگر بخش finally شامل عبارت return باشد، مقدار بازگشت داده شده، از عبارت return بخش finally خواهد بود، نه مقداری که عبارت return بخش try باز می گرداند.
برای مثال:
>>> def bool_return():
... try:
... return True
... finally:
... return False
...
>>> bool_return()
False
یک مثال پیچیده تر:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
</stdin></module></stdin>
همانطور که می بینید، بخش finally در هر شرایطی اجرا شده است. خطای TypeError که به واسطه تقسیم دو رشته بر هم اعلام شده است، توسط بخش except اداره نشده است، بنابراین پس از اجرای بخش finally دوباره اعلام می شود. در برنامه های دنیای واقعی، استفاده از بخش finally برای آزادسازی منابع خارجی (مانند فایل ها یا ارتباطات شبکه) مفید است، صرف نظر از اینکه آیا استفاده از منبع موفقیت آمیز بوده است.

 

آموزش عملیات تمیزکاری از قبل تعریف شده در برنامه نویسی پایتون
برخی از اشیا عملیات تمیزکاری استانداردی را تعریف می کنند که در زمانی که شی، دیگر مورد نیاز نیست انجام شوند، صرف نظر از اینکه عملیاتی که از آن شی استفاده می کرد موفق بود یا شکست خورد. مثال زیر را ببینید، که می خواهد یک فایل را باز کند و محتویات آن را روی صفحه نمایش چاپ کند.
for line in open("myfile.txt"):
print(line, end="")
مشکل این کد این است که، برای مدت زمان نامعلومی پس از اتمام اجرای این بخش، فایل را باز می گذارد. در کدهای ساده این مسئله ای نیست، اما برای برنامه های بزرگتر می تواند یک مشکل باشد. عبارت with این تضمین را می دهد تا اشیایی مانند فایل ها به گونه ای مورد استفاده قرار گیرند که همیشه فورا و به طور صحیحی تمیز شوند.
with open("myfile.txt") as f:
for line in f:
print(line, end="")
پس از اجرای این عبارت، فایل f همیشه بسته می شود، حتی اگر در حین پردازش خطوط با مشکلی مواجه شود. اشیایی (مانند فایل ها) که عملیات تمیزکاری از پیش تعریف شده را ارائه می کنند، آن را در مستندات خود توضیح می دهند.
دوره آموزش پایتون ادامه دارد
  • افشین رفوآ
  • ۰
  • ۰
سلام دوستان ...در قسمت قبل آموزش پایتون مفاهیم زیر را یاد دادیم
  • مقایسه دنباله ها و سایر انواع در برنامه نویسی Python
  • آموزش ماژول ها در برنامه نویسی پایتون
  • آموزش ماژول های استاندارد در برنامه نویسی پایتون
  • آموزش تابع dir() در برنامه نویسی پایتون
با ادامه آموزش پایتون همراه ما باشید.
 

 

آموزش خواندن و نوشتن فایل در زبان برنامه نویسی پایتون
دستور open() یک شی فایل (file object) را باز می گرداند، و در اکثر مواقع با دو آرگومان استفاده می شود:
open(filename, mode)
>>> f = open('workfile', 'w')
آرگومان اول یک رشته شامل نام فایل است. آرگومان دوم یک رشته دیگر شامل تعداد کمی کاراکتر است که روش استفاده از فایل را توصیف می کند. حالت (mode) می تواند r باشد برای زمانی که فایل فقط خوانده می شود، w برای فقط نوشتن (فایل موجود با نام مشابه پاک خواهد شد)، و a فایل را برای افزودن(append) باز می کند؛
هر داده ای که در فایل نوشته شود به صورت خودکار به انتهای فایل اضافه می شود. r+ فایل را برای خواندن و نوشتن باز می کند. آرگومان حالت اختیاری است.
در صوت حذف، r در نظر گرفته می شود. به طور معمول فایل ها در حالت متن(text) باز می شوند، این به این معنی است که شما رشته ها را از فایل می خوانید و درون فایل می نویسید، که این فایل به یک روش رمزنگاری خاص کدگذاری شده است.
اگر روش رمزنگاری مشخص نشده باشد، پیش فرض وابسته به پلتفرم(platform) است
اگر b به حالت اضافه شود، فایل در حالت باینری (binary) باز می شود.، حال، داده در قالب اشیای بایت خوانده و نوشته می شود. این حالت باید برای همه فایل هایی که شامل متن نیستند استفاده شود.
هنگام خواندن در حالت متن، پیش فرض این است که انتهای خطوط خاص هر پلتفرم (\n در Unix، \r\n در ویندوز) را فقط به \n تبدیل کند. هنگام نوشتن در حالت متن، پیش فرض این است که هر جا \n وجود دارد را به انتهای خطوط خاص هر پلتفرم بازگرداند. این تغییرات پشت پرده روی داده فایل برای فایل های متنی مشکلی ایجاد نمی کند، اما داده های باینری مانند فایل های JPEG یا EXE را خراب می کند.
در هنگام خواندن و نوشتن چنین فایل هایی بسیار مراقب استفاده از حالت باینری باشید. خوب است هنگام کار با اشیای فایل از کلمه کلیدی with استفاده کنید. مزیت آن این است که پس از اتمام مجموعه فایل، حتی درصورتی که در جایی یک استثنا رخ دهد، فایل به درستی بسته می شود. همچنین استفاده از with بسیار کوتاهتر از نوشتن بلاک try-finally برابر با آن است.
>>> with open('workfile') as f:
... read_data = f.read()
 
>>> # We can check that the file has been automatically closed.
>>> f.closed
True
اگر از کلمه کلیدی with استفاده نمی کنید، پس باید f.close() را فراخوانی کنید تا فایل را ببندد و فورا منابع سیستمی استفاده شده توسط آن را آزاد کند. اگر صریحا یک فایل را نبندید، زباله جمع کن پایتون (Python’s garbage collector) نهایتا شی را نابود می کند و فایل را برای شما می بندد، اما ممکن است برای مدتی فایل باز بماند. احتمال خطر دیگری که وجود دارد این است که پیاده سازی های مختلف پایتون، این عمل تمیز کردن را در زمان های مختلف انجام می دهند. پس از اینکه یک شی فایل بسته شد، تلاش برای استفاده از شی فایل چه از طریق عبارت with یا با فراخوانی f.close() ، به صورت خودکار شکست می خورد.
>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
</module></stdin>

 

آموزش متدهای اشیای فایل در آموزش پایتون
در بقیه مثال های این بخش فرض شده است که یک شی فایل به نام f پیش از این ایجاد شده است. برای خواندن محتویات یک فایل f.read(size) را فراخوانی کنید، که تعدادی داده را می خواند و به صورت یک رشته(در حالت متن) یا شی بایت (در حالت باینری) باز می گرداند.
سایز Size یک آرگومان عددی اختیاری است. زمانی که size حذف شود یا منفی باشد، کل محتویات فایل خوانده و باز گردانده می شود. این مشکل شماست اگر فایل دو برابر بزرگتر از حافظه سیستم شماست. در غیر این صورت، حداکثر اندازه کاراکتر (در حالت متن) یا اندازه بایت(در حالت باینری) خوانده و باز گردانده می شود. اگر به انتهای فایل رسیده باشیم، f.read() یک رشته خالی را باز می گرداند (‘ ‘).
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
دستور f.readline() یک خط از فایل را می خواند. کاراکتر خط جدید (\n) در انتهای رشته قرار می گیرد، و فقط زمانی حذف می شود که به آخرین خط فایل رسیده باشیم، و البته اگر فایل با خط جدید(\n) تمام نشود. این باعث می شود تا مقدار بازگشتی واضح باشد. اگر f.readline() یک رشته خالی را باز گرداند، به انتهای فایل رسیدیم، در حالی که یک خط خالی توسط \n نمایش داده شده است، یک رشته شامل تنها یک خط جدید.
>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''
برای خواندن خطوط از یک فایل، میتوانید روی شی فایل حلقه بزنید. این عمل از نظر حافظه کارآمد است، سریع است و ما را به یک کد ساده می رساند.
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
اگر می خواهید همه خطوط یک فایل را بخوانید و در یک لیست قرار دهید، می توانید از list(f) یا f.readlines() استفاده کنید. f.write(string) محتویات رشته را درون فایل می نویسد، و تعداد کاراکتر های نوشته شده را باز می گرداند.
>>> f.write('This is a test\n')
15
سایر انواع اشیا باید قبل از نوشته شدن، یا به یک رشته (در حالت متن) یا به یک شی بایت (در حالت باینری) تبدیل شوند.
>>> value = ('the answer', 42)
>>> s = str(value) # convert the tuple to string
>>> f.write(s)
18
دستور f.tell() یک عدد صحیح که مکان فعلی شی فایل را در فایل مشخص می کند، باز می گرداند. این مقدار بازگشتی به صورت عددی از بایت ها از آغاز فایل در حالت باینری و یک عدد opaque در حالت متن، نمایش داده می شود. برای تغییر مکان شی فایل، از f.seek(offset, whence) استفاده کنید.
مکان با افزودن offset به یک نقطه مرجع محاسبه می شود. نقطه مرجع توسط آرگومان whence انتخاب می شود. مقدار 0 برای whence ، از ابتدای فایل می سنجد، 1 از مکان فعلی استفاده می کند، و 2 از انتهای فایل به عنوان نقطه مرجع استفاده می کند. whence می تواند حذف شود و پیش فرض 0 است که از ابتدای فایل به عنوان نقطه مرجع استفاده می کند.
>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5) # Go to the 6th byte in the file
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # Go to the 3rd byte before the end
13
>>> f.read(1)
b'd'
در فایل های متنی(آنهایی که بدون b در رشته حالت، باز شده اند)، تنها جستجوهای وابسته به شروع فایل مجاز است (استثنای جستجو از انتهای فایل با seek(0, 2) انجام می شود) و تنها مقادیر معتبر offset آنهایی هستند که یا صفر باشند یا توسط f.tell() باز گردانده شده اند.
هر مقدار offset دیگری، رفتار تعریف نشده ای را تولید می کند. اشیای فایل، متدهای اضافی دیگری هم دارند، مانند isatty() و truncate() که کمتر مورد استفاده قرار میگیرند.

 

آموزش ذخیره داده ساخت یافته با استفاده از json در آموزش پایتون
رشته ها را می توان به سادگی از فایل خواند یا درون فایل نوشت. اعداد نیاز به تلاش بیشتری دارد، از آنجایی که متد read() فقط رشته باز می گرداند، باید به یک تابع مانند int() پاس داده شود، که یک رشته مانند ‘123’ را می گیرد و مقدار عددی آن یعنی 123 را باز می گرداند. زمانی که بخواهید انواع داده پیچیده تری مانند لیست های تو در تو و دیکشنری ها را ذخیره کنید، پارس کردن (parsing) و سریال سازی دستی پیچیده می شود.
به جای اینکه کاربران مدام به نوشتن و اشکال زدایی کد برای ذخیره انواع داده پیچیده در فایل بپردازند، پایتون به شما این امکان را می دهد تا از فرمت تبادل داده محبوب به نام JSON (نماد شی جاوا اسکریپت)استفاده کنید.
ماژول استاندارد json می تواند سلسله مراتب داده پایتون را بگیرد، و آنها را به نمایش های رشته ای تبدیل کند. این روند سریال سازی (serializing) نام دارد. بازسازی داده از نمایش رشته ای، محصور کردن (deserializing) نام دارد. بین سریال سازی و محصور کردن، رشته ای که نمایشگر شی است ممکن است در یک فایل یا داده ذخیره شده باشد، یا از طریق ارتباطات شبکه به یک سیستم دور فرستاده شده باشد.
توجه !
معمولا برای تبادل داده، فرمت JSON توسط برنامه های کاربردی مدرن استفاده می شود. در حال حاظر بسیاری از برنامه نویسان با آن آشنا هستند، و همین آن را به یک گزینه خوب برای همکاری تبدیل کرده است.
اگر شی x را داشته باشید، می توانید نمایش رشته ای JSON آن را با یک خط کد ساده ببینید:
>>> import json
>>> json.dumps([1, 'simple', 'list'])
'[1, "simple", "list"]'
گونه دیگری از تابع dumps()، dump() نام دارد، که به سادگی شی را به یک فایل متنی سریال سازی می کند. بنابراین اگر f یک شی فایل متنی باشد که برای نوشتن باز شده باشد، می توانیم این کار را انجام دهیم:
json.dump(x, f)
برای رمزگشایی مجدد شی، اگر f یک شی فایل متنی باشد که برای خواندن باز شده باشد:
x = json.load(f)
این روش ساده سریال سازی می تواند لیست ها و دیکشنری ها را مدیریت کند، اما سریال سازی اختیاری نمونه های کلاس در JSON نیاز به کمی تلاش بیشتر دارد. مرجع مربوط به ماژول json در بردارنده توضیحاتی برای این موضوع است.

 

آموزش خطاها و استثناها در برنامه نویسی پایتون
تا اینجا به پیام های خطا فقط اشاره کردیم، اما اگر مثال ها را انجام داده باشید احتمالا به برخی از آنها برخورده اید. حداقل دو نوع خطای متمایز وجود دارد: خطاهای نحوی(نگارشی- syntax) و استثناها.

 

آموزش خطاهای نحوی در Python
خطاهای نحوی که همچنین با نام خطاهای parsing نیز شناخته شده هستند، شاید معمول ترین نوع خطا باشد که در حین یادگیری پایتون به آن بر می خورید.
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
</stdin>

 

آموزش Parser در Python
خط دارای خطا را تکرار می کند و یک فلش کوچکی را نمایش می دهد که به اولین نقطه در خط، جایی که خطا تشخیص داده شده است، اشاره می کند. خطا توسط علامتی که قبل از فلش وجود دارد رخ داده است یا حداقل در آن نقطه تشخیص داده شده است.
در این مثال، خطا در تابع print() تشخیص داده شده است، زیرا یک دو نقطه (:) قبل از آن حذف شده است. نام فایل و شماره خط چاپ شده است، بنابراین در صورتی که ورودی از یک script بیاید می دانید کجا به دنبال خطا بگردید.

 

آموزش استثناها در برنامه نویسی پایتون
حتی اگر یک عبارت یا اصطلاح از نظر نگارشی صحیح باشد، ممکن است زمانی که قصد اجرای آن را داریم، باعث بروز خطا شود. خطاهای تشخیص داده شده در حین اجرا، استثنا نام دارد و بی قید و شرط مهلک نیستند: به زودی نحوه مدیریت آنها در برنامه های پایتون را فرا خواهید گرفت. اغلب استثناها توسط برنامه ها مدیریت نمی شوند، اگرچه منجر به پیام های خطا می شوند که در اینجا نشان داده شده است.
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
</module></stdin></module></stdin></module></stdin>
آخرین خط در پیام خطا، بیان می کند که چه اتفاقی افتاده است. استثناها انواع مختلفی دارند، و نوع آنها به عنوان بخشی از پیام چاپ می شود.
نوع خطاها در این مثال ZeroDivisionError ، NameError و TypeError است. رشته چاپ شده به عنوان نوع استثنا، نام استثنای داخلی (built-in exception) است که رخ داده. این امر برای همه استثناهای داخلی صحت دارد، اما نیاز نیست برای استثناهای تعریف شده توسط کاربر نیز صحت داشته باشد (هرچند این یک قرارداد مفید است).
به طور کلی شامل یک ردیابی پشته ای است که خطوط کد را لیست می کند. اگر چه خطوط خوانده شده از ورودی استاندارد را نمایش نمی دهد. لینک Built-in Exceptions استثناهای درونی را بر می شمارد و معانی آنها را می گوید.

 

آموزش مدیریت استثناها در آموزش پایتون
نوشتن برنامه هایی که استثناهای انتخاب شده را مدیریت کند امکان پذیر است. مثال زیر را ببینید که تا زمان دریافت عدد صحیح معتبر، از کاربر درخواست ورودی می کند.
اما به کاربر این امکان را می دهد که برنامه را قطع کند (با استفاده از کنترل +C و یا هر آنچه که سیستم عامل پشتیبانی می کند). توجه داشته باشید این قطع شدن برنامه که توسط کاربر رخ داده است با اعلام استثنای KeyboardInterrupt شناسانده می شود.
>>> while True:
... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
...
عبارت try به صورت زیر کار می کند.
  • ابتدا، بخش try (عبارات بین دو کلمه کلیدی try و except) اجرا می شود.
  • اگر هیچ استثنایی رخ ندهد، از روی بخش except می پرد( این بخش اجرا نمی شود) و اجرای عبارت try تمام می شود.
  • اگر در حین اجرای بخش try استثنایی رخ دهد، از اجرای بقیه این بخش صرف نظر می کند. سپس اگر نوع خطای رخ داده با نام خطای نوشته شده پس از کلمه کلیدی except یکسان باشد، بخش except اجرا می شود، و سپس اجرا از پس از عبارت try ادامه می یابد.
  • اگر استثنایی رخ دهد که مشابه نام استثنا در بخش except نباشد، به خارج از عبارات بخش try منتقل می شود. اگر هیچ بخش مدیریتی (handler) وجود نداشته باشد، یک استثنای مدیریت نشده رخ داده است و اجرا با پیامی که در بالا نشان داده شده است متوقف می شود.
یک عبارت try ممکن است برای مدیریت استثناهای مختلف، بیشتر از یک بخش except داشته باشد. حداکثر یک بخش مدیریتی اجرا خواهد شد. بخش های مدیریتی، تنها استثناهای رخ داده شده در بخش try مربوطه را مدیریت می کنند، نه در سایر بخش های مدیریتی از عبارت try مشابه. یک بخش استثنا ممکن است چندین استثنا را در قالب یک چندتایی پرانتز دار نام ببرد. برای مثال:
... except (RuntimeError, TypeError, NameError):
... pass
یک کلاس درون یک بخش except ، با یک استثنا سازگار است، اگر همان کلاس مشابه یا یک کلاس پایه باشد. (اما عکس آن صادق نیست- یک بخش except که یک کلاس مشتق شده را لیست کرده است با یک کلاس پایه سازگار نیست). برای مثال، کد زیر B ,C ,D را به این ترتیب چاپ می کند.
class B(Exception):
pass
 
class C(B):
pass
 
class D(C):
pass
 
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
 
توجه داشته باشید که اگر بخش های except معکوس شوند ( اول except B باشد)، B,B,B چاپ می شد—اولین بخش except فعال شده است.
آخرین بخش except ممکن است نام استثنا(ها) را حذف کند. از این قابلیت با احتیاط بسیار استفاده کنید، زیرا پنهان شدن یک خطای واقعی برنامه نویسی از این طریق به سادگی امکان پذیر است. همچنین از آن می توان برای چاپ یک پیام خطا و اعلام دوباره آن استثنا استفاده کرد (همچنین اجازه به فراخواننده برای مدیریت استثنا).
import sys
 
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
عبارت try … except دارای یک بخش else اختیاری است که در صورت وجود باید از همه بخش های استثنا پیروی کند. این برای کدی که بخش try آن استثنایی اعلام نکرده و باید اجرا شود، مفید است. برای مثال:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
 
استفاده از بخش else بهتر از افزودن کد اضافی به بخش try است، زیرا آن از گرفتن تصادفی استثنایی که توسط کدی که با عبارت try … except محافظت می شود، جلوگیری میکند. زمانی که یک استثنا رخ می دهد، ممکن است یک مقدار وابسته داشته باشد، که به عنوان آرگومان استثنا نیز شناخته می شود.
حضور و نوع آرگومان به نوع استثنا بستگی دارد. بخش except ممکن است یک متغیر را بعد از نام استثنا مشخص کند. متغیر به یک نمونه استثنا (exception instance) محدود است و آرگومان ها در instance.args ذخیره می شوند.
.برای سادگی، نمونه استثنا __str__() را تعریف می کند، بنابراین آرگومان ها می توانند مستقیما بدون نیاز به ارجاع به .args چاپ شوند. همچنین ممکن است ابتدا پیش از اعلام یک استثنا، مقدار دهی اولیه شود و هر ویژگی دلخواه به آن اضافه شود.
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'exception'="">
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
</class>
اگر یک استثنا دارای آرگومان باشد، آنها همانند بخش آخر (‘detail’) پیام برای استثناهای مدیریت نشده، چاپ می شوند. بخش مدیریت استثنا فقط استثناها را در صورت وقوع فوری در بخش try مدیریت نمیکند، بلکه اگر درون توابع بخش try فراخوانی شوند یا حتی مستقیما در آن توابع رخ دهند نیز مدیریت می شوند. برای مثال:
>>> def this_fails():
... x = 1/0
...
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print('Handling run-time error:', err)
...
Handling run-time error: division by zero
آموزش پایتون ادامه دارد
  • افشین رفوآ
  • ۰
  • ۰

سلام دوستان ...در قسمت قبل آموزش پایتون مفاهیم زیر را یاد دادیم

لینک قسمت اول آموزش پایتون

  • مقایسه دنباله ها و سایر انواع در برنامه نویسی Python
  • آموزش ماژول ها در برنامه نویسی پایتون
  • آموزش ماژول های استاندارد در برنامه نویسی پایتون
  • آموزش تابع dir() در برنامه نویسی پایتون

 

با ادامه آموزش پایتون همراه ما باشید.

آموزش پکیج ها در برنامه نویسی پایتون

پکیج (package) روشی برای ساخت فضای نام (namespace) ماژول پایتون با استفاده از " نام ماژول های نقطه گذاری شده" است.

برای مثال، نام ماژول A.B تعیین کننده یک زیر ماژول به نام B در پکیجی به نام A است. همانند کاربرد ماژول ها که نویسنده ماژول های مختلف را از نگرانی درباره نام متغیر های سراسری هم دیگر می رهاند، استفاده از نام ماژول های نقطه گذاری شده نیز نویسنده پکیج های چند ماژولی مانند NumPy و Pillow را از نگرانی درباره نام ماژول های یکدیگر می رهاند.

فرض کنید می خواهید برای مدیریت یکپارچه فایل ها و داده های صوتی، مجموعه ای از ماژول ها (یک پکیج) را طراحی کنید. فایل های صوتی فرمت های بسیار مختلفی دارند (که معمولا توسط دنباله خود شناخته می شوند مانند .wav , .aiff , .au) ، بنابراین ممکن است مجبور شوید یک مجموعه در حال رشد از ماژول ها را برای تبدیل فرمت های مختلف به هم ایجاد و نگهداری کنید. همچنین ممکن است بخواهید عملیات مختلف زیادی را روی داده های صوتی اعمال کنید (مانند ترکیب کردن، افزودن پژواک، اعمال یک تابع برابر کننده، ساخت یک اثر stereo مصنوعی)، بنابراین شما جریانی از ماژول هایی که هیچگاه تمام نمیشود را برای انجام این عملیات خواهید نوشت. در اینجا یک ساختار محتمل برای پکیج شما وجود دارد (در غالب سیستم فایل سلسله مراتبی بیان شده است).

 

sound/                          Top-level package

__init__.py               Initialize the sound package

formats/                  Subpackage for file format conversions

        __init__.py

        wavread.py

        wavwrite.py

       aiffread.py

        aiffwrite.py

        auread.py

        auwrite.py

        ...

effects/                  Subpackage for sound effects

        __init__.py

        echo.py

        surround.py

        reverse.py

        ...

filters/                  Subpackage for filters

        __init__.py

        equalizer.py

        vocoder.py

        karaoke.py

        ...

هنگامی که پکیج را وارد (import) می کنید، پایتون برای پیدا کردن زیر دایرکتوری پکیج، درون دایرکتوری های روی sys.path را جستجو می کند. برای این که پایتون دیکشنری های حاوی فایل را به عنوان پکیج بشناسد، به فایل های __init__.py نیاز دارد.

این کار مانع از این می شود تا دیکشنری هایی با نام های متداول مانند string ، به طور غیر عمد ماژول های معتبری که بعدا در مسیر جستجوی ماژول قرار میگیرند را پنهان کنند. در ساده ترین حالت، __init__.py می تواند فقط یک فایل خالی باشد، اما همچنین می تواند کد مقدار دهی اولیه (اولیه سازی) برای پکیج را اجرا کند یا متغیر __all__ variable که بعدا توضیح داده می شود را تنظیم کند. کاربران پکیج می توانند ماژول های مجزا را از پکیج وارد کنند، برای مثال:

import sound.effects.echo

این دستور زیر ماژول sound.effects.echo را بار گذری می کند، و باید به نام کامل آن ارجاع داده شود.

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

روش جایگزین برای وارد کردن زیر ماژول به این صورت است:

from sound.effects import echo

این دستور همچنین زیر ماژول echo را نیز بار گذاری می کند، و آن را بدون پسوند پکیج خود، در دسترس قرار می دهد، بنابراین میتوان به صورت زیر از آن استفاده کرد:

echo.echofilter(input, output, delay=0.7, atten=4)

علاوه بر آن می توان تابع یا متغیر دلخواه را مستقیما وارد کرد:

from sound.effects.echo import echofilter

 

دوباره، این دستور زیر ماژول echo را بار گذاری می کند، اما تابع echofilter() آن را مستقیما در دسترس قرار می دهد.

echofilter(input, output, delay=0.7, atten=4)

توجه داشته باشید در هنگام استفاده از from package import item ، آیتم می تواند یک زیر ماژول (یا زیر پکیج) از پکیج باشد، یا هر نام دیگری که در پکیج تعریف شده باشد، مانند یک تابع، کلاس یا متغیر. عبارت import در ابتدا بررسی می کند که آیا آیتم در پکیج تعریف شده است، اگر تعریف نشده باشد، فرض می کند که آن یک ماژول است و برای بارگذاری آن اقدام می کند.

اگر در پیدا کردن آن شکست بخورد، استثنای ImportError رخ می دهد. در مقابل، هنگامی که از نحوه نگارش import item.subitem.subsubitem استفاده می کنید، همه آیتم ها به جز مورد آخر باید یک پکیج باشند. آیتم آخر می تواند یک ماژول یا یک پکیج باشد اما نمیتواند یک کلاس یا تابع یا متغیر تعریف شده در آیتم های قبلی باشد.

وارد کردن * از یک پکیج در آموزش پایتون

حال اگر کاربر from sound.effects import * را بنویسد چه اتفاقی می افتد؟

در شرایط ایده آل می توان امیدوار بود که به طریقی به سیستم فایل برود و زیر ماژول های حاضر در پکیج را پیدا کند و همه آنها را وارد کند. این کار می تواند زمان زیادی طول بکشد و وارد کردن زیر ماژول ها می تواند اثرات جانبی ناخواسته ای داشته باشد که باید تنها زمانی که زیر ماژول صریحا وارد می شود اتفاق افتد. تنها راه حل این است که نویسنده پکیج یک اندیس صریح از پکیج را ارائه کند. عبارت import از قرارداد زیر استفاده می کند:

اگر کد __init__.py یک پکیج، یک لیست به نام __all__ را تعریف کند، فرض می شود که لیستی از نام ماژول هایی است که در صورت مواجهه با from package import * ، باید وارد شود.

در زمانی که نسخه جدیدی از پکیج ارائه می شود، به روز نگه داشتن این لیست به عهده نویسنده پکیج است. همچنین ممکن است نویسنده پکیج تصمیم بگیرد در صورتی که کاربردی برای وارد کردن * از پکیج آنها نبینند، از آن پشتیبانی نکند. برای مثال، فایل sound/effects/__init__.py می تواند شامل کد زیر باشد:

 

__all__ = ["echo", "surround", "reverse"]

این به این معنی است که from sound.effects import * سه زیر ماژول نام برده شده از پکیج sound را وارد می کند. اگر __all__ تعریف نشده باشد، عبارت from sound.effects import * تمامی زیر ماژول های پکیج sound.effects را درون فضای نام فعلی وارد نمی کند.

این عبارت فقط تضمین می کند که پکیج sound.effects وارد شده است (احتمالا اجرای هر کد اولیه سازی در __init__.py) و سپس هر نام تعریف شده در پکیج را وارد می کند. این شامل هر نام (و زیر ماژول هایی که صریحا بارگذاری شده اند) تعریف شده توسط __init__.py می باشد. همچنین شامل هر زیر ماژولی از پکیج است که توسط عبارت import قبلی صریحا بارگذاری شده باشد. این کد را در نظر بگیرید:

 

import sound.effects.echo

import sound.effects.surround

from sound.effects import *

 

در این مثال، ماژول های echo و surround در فضای نام فعلی وارد شده اند، زیرا زمانی که عبارت from...import اجرا می شود، آنها در پکیج sound.effects تعریف شده اند. (همچنین زمانی که __all__ تعریف شده است نیز عمل می کند.) با وجود اینکه ماژول های خاصی برای فقط صادر کردن(export) نام هایی که در هنگام استفاده از import * از الگوهای خاصی پیروی می کنند طراحی شده است، این، همچنان عملکرد بد در تولید کد در نظر گرفته می شود. به یاد داشته باشید، هیچ مشکلی در استفاده از from package import specific_submodule وجود ندارد.

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

ارجاع های درونی پکیج (intra-package) در Python

زمانی که پکیج ها درون زیر پکیج ها ساخته می شوند ( مانند پکیج sound در مثال)، می توانید از واردات مستقل (absolute imports) برای ارجاع به زیر ماژول های پکیج های هم خانواده استفاده کنید.

برای مثال، اگر ماژول sound.filters.vocoder نیاز به استفاده از ماژول echo در پکیج sound.effects داشته باشد، می تواند از from sound.effects import echo استفاده کند. همچنین می توانید واردات وابسته (relative imports) را در قالب from module import name از عبارات واردات بنویسید. این واردات از نقاط راهنما برای بیان پکیج های فعلی و والد درگیر در واردات وابسته استفاده می کند. برای مثال ممکن است از ماژول surround استفاده کنید:

توجه داشته باشید که واردات وابسته مبتنی بر نام ماژول فعلی هستند. از آنجایی که نام ماژول اصلی همیشه "__main__" است، ماژول هایی که برای استفاده به عنوان ماژول اصلی برنامه پایتون در نظر گرفته می شوند، همیشه باید از واردات مستقل استفاده کنند.

پکیج ها در چندین دایرکتوری در آموزش پایتون

پکیج ها از یک ویژگی خاص دیگر به نام __path__ نیز پشتیبانی می کنند. این به گونه ای مقدار دهی اولیه شده است که یک لیست شامل نام دایرکتوری باشد که _init__.py مربوط به پکیج را قبل از اینکه کد درون آن فایل اجرا شود، نگه می دارد.

. این متغیر قابل تغییر است، این کار روی جستجو های آینده در زمینه ماژول ها و زیر پکیج های موجود در پکیج تاثیر می گذارد. هر چند که این ویژگی اغلب مورد نیاز نیست، از آن می توان برای توسعه مجموعه ماژول های موجود در یک پکیج استفاده کرد.

توجه !

‌در واقع تعریف توابع عباراتی هستند که اجرا می شوند. اجرای تعریف یک تابع در سطح ماژول، وارد نام تابع در جدول نماد سراسری ماژول می شود.

آموزش ورودی و خروجی در پایتون

چندین روش برای نمایش خروجی یک برنامه وجود دارد. می توان داده را به صورت قابل خواندن برای انسان چاپ کرد، یا برای استفاده در آینده درون یک فایل نوشت. در این بخش درباره برخی از روش ها صحبت خواهیم کرد.

قالب بندی تفننی خروجی (fancier output formatting) در برنامه نویسی Python

تا اینجا با دو روش نوشتن مقادیر آشنا شده ایم: عبارات اصطلاحی و تابع print() . ( روش سوم استفاده از متد write() اشیای فایل است. به فایل خروجی استاندارد به عنوان sys.stdout می توان ارجاع داد. برای اطلاعات بیشتر در این زمینه بخش مرجع کتابخانه (Library Reference) را ببینید.) شما اغلب خواهان کنترل بیشتری روی قالب خروجی خود هستید تا اینکه فقط خروجی را به صورت مقادیر جدا شده با فاصله چاپ کنید.

در این جا چندین روش برای قالب بندی خروجی ارائه شده است.

  • برای استفاده از حروف رشته قالب بندی شده، یک رشته را با f یا F قبل از باز کردن گیومه نقل قول یا نقل قول سه تایی شروع کنید. درون این رشته، می توانید یک عبارت پایتون را بین کاراکترهای { و } بنویسید که بتواند به مقادیر متغیر ها و حروف ارجاع دهد.

 

  • افشین رفوآ