GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

No menu could be recovered. Follow the blue links in the page.

This view

  • Original page
  • New address

GeezerVison is showing pythonpersian.com — درس ۲۰: شی گرایی (OOP) در پایتون: Encapsulation و چندریختی (Polymorphism) — کتاب پایتون به پارسی

پایتون به پارسی
  • پیش‌گفتار
  • درس ۰۱: آشنایی با زبان برنامه‌نویسی پایتون
    • تاریخچه
    • توصیفی کوتاه
    • مفسر زبان پایتون
    • ویژگی‌ها
    • کارایی
    • نسخه‌ها
    • پی‌نوشت
  • درس ۰۲: نصب و راه‌اندازی پایتون
    • دانلود
    • نصب در ویندوز
    • نصب در گنولینوکس
    • سیستم مدیریت بسته
  • درس ۰۳: چگونگی ایجاد و اجرای یک پروژه پایتون
    • تعاریف
    • ایجاد سورس کد
    • اجرای سورس کد
    • برنامه‌نویسی ماژولار
    • پشت صحنه اجرا
    • ایجاد محیط مجازی
    • انتشار پروژه
  • درس ۰۴: برنامه‌نویسی تعاملی با پایتون
    • حالت تعاملی
    • دریافت راهنمایی
    • گزینه‌های فراخوانی
    • پی‌نوشت
  • درس ۰۵: مفهوم شی‌گرایی
    • برنامه‌نویسی شی‌گرا
    • مفاهیم شی‌گرایی
    • اشیا در پایتون
    • کلاس‌ها در پایتون
  • درس ۰۶: سینتکس زبان پایتون
    • سطرها
    • مستند‌سازی
    • تورفتگی
    • دستور
    • شناسه
    • متغیر
    • NoneType
    • عملگر‌ها
    • پی‌نوشت
  • درس ۰۷: انواع داده در پایتون: عددی
    • انواع عددی
    • صحیح (Integer)
    • ممیز شناور (float)
    • مختلط (Complex)
    • دسیمال (Decimal)
    • کسر (Fraction)
    • بولی (Boolean)
  • درس ۰۷: انواع داده در پایتون: str و bytes
    • نوع رشته (str)
    • نوع داده باینری (bytes)
  • درس ۰۸: ساختمان‌های داده در پایتون: list و tuple
    • لیست
    • توپِل
  • درس ۰۸: ساختمان‌های داده در پایتون: set و dict
    • دیکشنری
    • مجموعه
    • دسته‌بندی
  • درس ۰۹: دستورهای کنترلی در پایتون
    • انتخاب
    • تکرار
    • شی تکرارکننده (iterator)
  • درس ۱۰: فایل، ورودی و خروجی (I/O) در پایتون
    • فایل‌ها
    • شی فایل استاندارد
    • تابع ()input
    • تابع ()print
    • ساختارهای ذخیره و تبادل داده
  • درس ۱۱: کتابخانه استاندارد پایتون
    • math
    • os
    • os.path
  • چالش کد پایتون: پایه
    • مساحت دایره
    • اعداد بخش‌پذیر بر هشت
    • میانگین نمره دانش‌آموزان (فایل CSV)
    • اشتراک دو لیست از اعداد
    • تبدیل نمره
    • تفاضل بزرگترین و کوچکترین عضو یک لیست از اعداد
    • محاسبه عبارت n+nn+nnn
    • وارونه‌سازی اسم
    • پالیندروم
    • گزارش دانش‌آموزان
    • شمارش حروف صدادار
    • رسم مثلث خیام-پاسکال
  • درس ۱۲: تابع در پایتون
    • مقدمه
    • سینتکس
    • فضاهای نام و حوزه
    • ارسال آرگومان
    • تطابق آرگومان‌ها
  • درس ۱۳: تابع در پایتون: Generator ،Decorator‌ و lambda
    • Decorator
    • Generator
    • در ادامه Coroutine :yield
    • List Comprehensions
    • Generator Expressions
    • lambda و توابع ناشناس
  • درس ۱۴: تابع در پایتون: تابع بازگشتی (Recursive) و Memoization
    • تابع بازگشتی
    • Function Attributes
    • Built-in Functions
    • Documentation Strings
  • درس ۱۵: عبارات با قاعده (Regular Expression) یا RegEx در پایتون
    • عبارات باقاعده
    • ماژول re پایتون
  • درس ۱۶: ماژول re (عبارات باقاعده) پایتون
    • توابع جستجو، ماژول re پایتون
    • توابع جایگزینی، ماژول re پایتون
    • توابع جداسازی، ماژول re پایتون
  • درس ۱۷: شی گرایی (OOP) در پایتون: تعریف کلاس و ایجاد شی
    • برنامه‌نویسی شی گرا (Object-Oriented Programming)
    • تعریف کلاس (Class)
    • نمونه‌سازی (Instantiation)
    • صفات (Attributes)
    • متد (Method)
    • مقدار Hash یک شی و کاربرد آن در پایتون
  • درس ۱۸: شی گرایی (OOP) در پایتون: وراثت (Inheritance)، Association و Mixin
    • وراثت (Inheritance)
    • انجمن (Association)
    • Mixin
  • درس ۱۹: شی گرایی (OOP) در پایتون: متا کلاس (Metaclass) و انتزاع (Abstraction)
    • متاکلاس (Metaclass)
    • انتزاع (Abstraction)
  • درس ۲۰: شی گرایی (OOP) در پایتون: Encapsulation و چندریختی (Polymorphism)
    • کپسوله‌سازی (Encapsulation)
    • چندریختی (Polymorphism)
  • درس ۲۱: شی گرایی (OOP) در پایتون: Context Manager ،Descriptors ،Decorator
    • __slots__
    • Decorators
    • Descriptors
    • property@
    • Context Manager و دستور with/as
  • درس ۲۲: شی گرایی (OOP) در پایتون: Type Hinting و دیتا کلاس (Data Class)
    • Type Hinting
    • Data Classes
  • درس ۲۳: مدیریت خطا در پایتون: Exception ،Traceback و Exception Handling
    • مقدمه
    • ردیابی خطا در پایتون (Traceback)
    • مدیریت خطا (Exception Handling)
    • Exception Hierarchy
  • درس ۲۴: مدیریت خطا در پایتون: Warning ،raise Exception و Assertion
    • دستور raise
    • ایجاد Exception
    • ماژول warnings
    • دستور assert
  • درس ۲۵: زمان در پایتون: ماژول‌ datetime
    • ماژول datetime
    • کلاس datetime.timedelta
    • کلاس datetime.tzinfo
    • کلاس datetime.date
    • کلاس datetime.time
    • کلاس datetime.datetime
    • متدهای strftime و strptime
  • گزارش توسعه
  • حمایت مالی
    • پرداخت ریالی
    • پرداخت ارزی
    • رمزارز
    • غیرنقدی
  • گزارش حمایت‌های مالی
  • محیط تعاملی پایتون
  • بهترین منابع آموزش پایتون
    • آموزش جامع
    • متن‌باز فارسی
"نه مرگ آنقدر ترسناک است و نه زندگی آنقدر شیرین که انسان برای این دو شرفش را بدهد" نامتان جاوید باد
  فهرست    درس ۲۰: شی گرایی (OOP) در پایتون: Encapsulation و چندریختی (Polymorphism)   سورس
گزارش حمایت
حمایت مالی
Star

درس ۲۰: شی گرایی (OOP) در پایتون: Encapsulation و چندریختی (Polymorphism)¶

شی گرایی (OOP) در پایتون: Encapsulation و چندریختی (Polymorphism)

Photo by sanjiv nayak¶

این درس در ادامه دروس گذشته مرتبط با آموزش شی گرایی در زبان برنامه‌نویسی پایتون می‌باشد. تاکنون با دو تا از چهار مفهوم مهم در شی‌گرایی آشنا شده‌ایم: وراثت (Inheritance) - درس هجدهم و انتزاع (Abstraction) - درس نوزدهم. این درس به بررسی دو مورد باقی‌مانده، یعنی کپسوله‌سازی (Encapsulation) و چندریختی (Polymorphism) در زبان برنامه‌نویسی پایتون می‌پردازد.

✔ سطح: متوسط



کپسوله‌سازی (Encapsulation)¶

در مبحث شی گرایی به پنهان‌سازی اطلاعات درونی یک شی و محدود کردن دسترسی به آن‌ها از بیرون، کپسوله‌سازی (Encapsulation) گفته می‌شود - در واقع Encapsulation برابر است با Information hiding.

پیش از هر چیزی لازم است بدانیم که زبان برنامه‌نویسی پایتون از فلسفه‌ای پیروی می‌کند که در جمله «اینجا همه بزرگسال هستیم» "we are all consenting adults here" خلاصه می‌شود! بنابراین این زبان برخلاف زبان‌هایی مانند Java و ++C یک Encapsulation قوی (strong) در اختیار برنامه‌نویس قرار نمی‌دهد. پایتون به برنامه‌نویس اعتماد دارد و می‌گوید «اگر دوست داری در مکان‌های تاریک پرسه بزنی، من مطمئنم که دلیل خوبی داری و هیچ مشکلی ایجاد نمی‌کنی!»

نکته

به صورت پیش‌فرض تمام اجزای داخلی یک کلاس، public هستند و از هر جایی خارج از کلاس مرتبط خود، قابل دستیابی می‌باشند.

نکته

بر اساس یک قرارداد مابین برنامه‌نویسان پایتون،‌ چنانچه ابتدای نام Attributeها و Methodها با یک کاراکتر خط زیرین (_) آغاز شود، این مفهوم را با خود می‌رساند که «دست نزنید مگر داخل همان کلاس یا subclassهای آن». رعایت این قرارداد معادل سطح دسترسی protected در Java و ++C می‌باشد.

نکته

زبان برنامه‌نویسی پایتون از تکنیک «دستکاری نام» یا name mangling [ویکی‌پدیا] پشتیبانی می‌کند. به کمک این تکنیک و با قراردادن دو کاراکتر خط زیرین (__) در ابتدای نام هر یک از اجزای داخلی یک کلاس (Attributeها و Methodها)، می‌توان معادل سطح دسترسی private در Java و ++C را پیاده‌سازی کرد [اسناد پایتون].

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

 1class Student:
 2
 3    def __init__(self, name, score=0):
 4        self.name = name
 5        self.__score = score
 6
 7    def display(self):
 8        print('name:', self.name)
 9        print('score:', self.__score)
10
11
12student = Student('Saeid', 70)
13
14#accessing using method
15student.display()
16
17#accessing directly from outside
18print('-' * 10, 'Accessing directly from outside')
19print('name:', student.name)
20print('score:', student.__score)
name: Saeid
score: 70
---------- Accessing directly from outside
name: Saeid
Traceback (most recent call last):
  File "sample.py", line 20, in <module>
    print('score:', student.__score)
AttributeError: 'Student' object has no attribute '__score'

داده‌های private را در خارج از کلاس نمی‌توان مستقیم مورد دستیابی قرار داد و همانطور که از نمونه کد بالا مشاهده می‌شود دستیابی چنین عناصری در پایتون باعث بروز AttributeError می‌شود. اما گفته شد که پایتون Encapsulation قوی ندارد، چه اتفاقی افتاد؟

مفسر پایتون بر اساس تکنیک name mangling، نام تمام عناصری (Attributeها و Methodها) که تنها با دو کاراکتر خط زیرین شروع شده باشند (مانند spam__) را به صورت زیر با افزودن نام کلاس به ابتدای آن تغییر می‌دهد:

_classname__spam

بنابراین اگر برنامه‌نویسی به دنبال دستیابی نام موجود (spam__) در کلاس باشد، چیزی پیدا نخواهد کرد. با این کار پایتون به صورت نسبی امکان دور نگه‌داشتن عناصر را از حالت عمومی فراهم آورده است. برای مثال پیش داریم:

>>> dir(student)
['_Student__score', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'display', 'name']

متدهای Setter و Getter¶

در برنامه‌نویسی شی گرا چنانچه بخواهیم دسترسی به داده‌ای را به شدت محدود کنیم، به آن داده سطح دسترسی private را اعمال می‌کنیم. اما گاهی می‌خواهیم تنها روند دستیابی و تغییر برخی از داده‌ها را کنترل کنیم - دسترسی مجاز است ولی چگونگی آن مهم است - در این صورت علاوه بر تنظیم سطح دسترسی private به آن عناصر متدهایی را برای تغییر (به عنوان Setter) و دستیابی (به عنوان Getter) آن‌ها نیز می‌بایست ایجاد کنیم:

 1class Student:
 2
 3    def __init__(self, name, score=0):
 4        self.name = name
 5        self.__score = score
 6
 7    def set_score(self, score):
 8        if isinstance(score, int) and  0 <= score <= 100:
 9            self.__score = score
10
11    def get_score(self):
12        return self.__score
13
14
15student = Student('Saeid', 70)
16student.set_score(99)
17student.set_score('100')
18student.set_score(-10)
19print(f'{student.name}, score:', student.get_score())
Saeid, score: 99

چندریختی (Polymorphism)¶

چندریختی از کلمات یونانی Poly (زیاد) و Morphism (ریخت) گرفته شده است و در برنامه‌نویسی شی گرا به این معنی است که از یک نام یکسان متد برای انواع مختلف می‌توان استفاده کرد.

در مبحث برنامه‌نویسی شی گرا به شیوه‌های زیر می‌توان چندریختی (Polymorphism) را پیاده‌سازی کرد:

  • Method Overriding

  • Method Overloading

  • Operator Overloading

در ادامه به بررسی و پیاده‌سازی هر مورد در زبان برنامه‌نویسی پایتون خواهیم پرداخت.

Method Overriding¶

این نوع از چندریختی در هنگام پیاده‌سازی وراثت (Inheritance - درس هجدهم) قابل استفاده است و تا کنون نیز بارها از آن بهره گرفتیم!.

در واقع به پیاده‌سازی دوباره یک متد از کلاس superclass در کلاس subclass را Method Overriding می‌گویند. در این مواقع متد superclass در زیر سایه متد هم نام در subclass قرار می‌گیرد و هنگام فراخوانی متد توسط اشیای کلاس subclass، این متد subclass است که فراخوانی می‌گردد:

 1class Animal:
 2
 3    def breathe(self):
 4      print('Animal, breathing...')
 5
 6    def walk(self):
 7      print('Animal, walking...')
 8
 9
10class Dog(Animal):
11
12    def walk(self):
13      print('Dog, walking...')
14
15
16dog = Dog()
17dog.breathe()
18dog.walk()
Animal, breathing...
Dog, walking...

در این نمونه کد، کلاس Dog از کلاس Animal ارث‌بری دارد و متد walk از کلاس Animal را Override کرده است. همانطور که از خروجی مشاهده می‌شود، برخلاف متد breathe، هنگام فراخوانی متد walk توسط شی Dog، متد باز‌پیاده‌سازی شده موجود در این کلاس فراخوانی می‌شود.

نکته

همان‌طور که پیش‌تر نیز انجام می‌دادیم، چنانچه تمایل به فراخوانی متد متناظر در superclass را داشته باشیم، می‌توانیم از تابع super استفاده کنیم.

نکته

اتفاقی که در بحث انتزاع (Abstraction) و ارث‌بری از کلاس‌های Abstract شاهد بودیم نیز در واقع پیروی از همین مبحث بوده و با این تفاوت که Method Overriding اجباری می‌بود.

نکته

در زبان برنامه‌نویسی پایتون تنها این نام متدهاست که در Method Overriding نقش دارد و تعداد پارامترهای تعریف شده در هر متد مهم نمی‌باشد. بنابراین متد همنام موجود در subclass می‌تواند پارامترهای متفاوتی نسبت superclass داشته باشد. البته تغییر در پارامترهای متد باز‌پیاده‌سازی شده چیزی نیست که بخواهیم آن را پیشنهاد بدهیم (به خصوص در بحث پیاده‌سازی متدهای Abstract) چرا که یکی از پیامدهای آن شکسته شدن اصل Liskov Substitution Principle [ویکی‌پدیا] می‌شود.

Method Overloading¶

این نوع از چندریختی به امکان کنارهم قرار گرفتن چندین متد همنام ولی با پارامترهای متفاوت (از نظر تعداد یا نوع) در کنار هم می‌باشد. یک شی می‌تواند با ارسال آرگومان‌های متفاوت و فراخوانی یک نام یکسان از متد، کارهای متفاوتی را به انجام برساند.

همانطور که در قسمت پیش نیز اشاره شد، در زبان برنامه‌نویسی پایتون تعداد و نوع پارامترهای تعریف شده برای یک تابع یا متد، هیچ ارتباطی با هویت آن متد ندارد و یک متد تنها با نام آن شناسایی می‌شود. بنابراین Method Overloading در پایتون پشتیبانی نمی‌شود و چنانچه چندین متد یا تابع همنام با پارامترهای متفاوت در یک کلاس یا ماژول در کنار هم باشند، خطایی رخ نمی‌دهد ولی باید توجه داشته باشید که متد یا تابع آخر، تمام موارد پیش از خود را در زیر سایه خواهد گرفت:

 1class Animal:
 2
 3    def breathe(self):
 4        print('breathing...')
 5
 6    def walk(self):
 7        print('walking...')
 8
 9    def walk(self, time=30):
10        print(f'{time} minutes, walking...')
11
12    def walk(self, minutes=30, seconds=59):
13        print(f'{minutes} minutes and {seconds} seconds, walking...')
14
15
16animal = Animal()
17animal.walk()
30 minutes and 59 seconds, walking...

همان‌طور که از خروجی نمونه کد بالا مشاهده می‌شود، با فراخوانی متد walk توسط شی Animal، از میان سه متد تعریف شده، این آخرین متد است که اجرا می‌گردد.

Operator Overloading¶

گونه‌ای از مفهوم چندریختی که در زبان برنامه‌نویسی پایتون پشتیبانی می‌شود، Operator Overloading می‌باشد که به انجام عملیات متفاوت با استفاده یک عملگر (Operator - درس ششم) یکسان اشاره دارد. برای مثال عملگر + هنگامی که به همراه دو شی int قرار بگیرد عمل جمع ریاضی (arithmetic addition) را بین آن دو به انجام می‌رساند ولی زمانی که با دو شی str قرار بگیرد، مقدار آن دو شی رشته را به یکدیگر پیوند می‌دهد (concatenate):

>>> a = 3
>>> b = 'string'

>>> a + a
6
>>> b + b
'stringstring'

زیان برنامه‌نویسی پایتون این قابلیت را در اختیار برنامه‌نویس قرار می‌دهد که بتواند عملیات مورد نظر خود را برای اشیای خود در هنگام مواجه با عملگرها فراهم آورد. این کار با استفاده از پیاده‌سازی برخی متدهای خاص ممکن می‌شود و در ادامه به معرفی متدهای معادل چند عملگر پایتون می‌پردازیم. توجه داشته باشید که تعداد این متدهای بسیار بیشتر از این‌ها بوده و در ازای تمام عملگرهای ممکن، یک متد نظیر قابل پیاده‌سازی می‌باشد، برای مطالعه بیشتر می‌توانید به مستندات پایتون مراجعه نمایید:

Binary Operators

Magic Metods

+

__add__(self, other) [اسناد پایتون]

-

__sub__(self, other) [اسناد پایتون]

*

__mul__(self, other) [اسناد پایتون]

/

__truediv__(self, other) [اسناد پایتون]

//

__floordiv__(self, other) [اسناد پایتون]

٪

__mod__(self, other) [اسناد پایتون]

**

__pow__(self, other) [اسناد پایتون]


Comparison Operators

Magic Metods

<

__lt__(self, other) [اسناد پایتون]

>

__gt__(self, other) [اسناد پایتون]

<=

__le__(self, other) [اسناد پایتون]

>=

__ge__(self, other) [اسناد پایتون]

==

__eq__(self, other) [اسناد پایتون]

!=

__ne__(self, other) [اسناد پایتون]



به عنوان نمونه یک کلاس Number جدید می‌سازیم و عملگر + در آن پیاده‌سازی می‌کنیم:

 1class Number:
 2
 3    def __init__(self, number):
 4        self.number = number
 5
 6    # adding two objects
 7    def __add__(self, other_number):
 8        return self.number + other_number.number
 9
10
11a = Number(5)
12b = Number(7)
13
14result = a + b
15
16print(f'{a.number } + {b.number } =', result)
5 + 7 = 12

به عنوان مثالی دیگر، شخصی‌سازی سنجش برابر بودن دو شی:

 1class Student:
 2
 3    def __init__(self, name, score=0):
 4        self.name = name
 5        self.score = score
 6
 7    def __eq__(self, other_student):
 8       return self.score == other_student.score
 9
10
11a = Student('Saeid', 75)
12b = Student('Babak', 75)
13
14print(a == b)
True


😊 امیدوارم مفید بوده باشه

  قبلی بعدی  

این کتاب متن‌باز و آزاد است

از تلاش برای ایجاد و نگهداری این کتاب حمایت کنید!

حمایت مالی

Creative Commons License 2015, Saeid Darvishghazvini

Created using Sphinx (9.0.4) with Minoo (0.9.7) theme.

تماس با نویسنده

حمایت مالی
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.