FA-TOOLS — Header Component

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

نقشه راه یادگیری شیءگرایی در پایتون (یک نگاه سریع)

آموزش کلاس و شیءگرایی در پایتون برای مبتدیان — تصویر 1

🌟 شروع سفر

  • چرا OOP؟ (مزایا و کاربرد)
  • مفهوم کلاس و شیء
  • خصوصیات (Attributes) و متدها (Methods)

🛠️ ساخت و ساز

  • تعریف کلاس و ساخت شیء
  • متد `__init__` (سازنده)
  • کار با متدها و ویژگی‌ها

🚀 مفاهیم پیشرفته

  • ارث‌بری (Inheritance)
  • چندریختی (Polymorphism)
  • کپسوله‌سازی (Encapsulation)

🎯 حل مشکلات

  • عیب‌یابی سریع (Troubleshooting)
  • پرسش‌های متداول (FAQ)
  • نکات پایانی

با ما همراه باشید تا گام به گام در این مسیر جذاب قدم برداریم!

تماس برای مشاوره یا پشتیبانی: 09202232789

یادگیری پایتون یه سفر هیجان‌انگیزه، مخصوصاً وقتی پات رو تو دنیای شیءگرایی می‌ذاری. خیلی از برنامه‌نویس‌های تازه کار فکر می‌کنن شیءگرایی (OOP) یه مفهوم پیچیده و دغدغه‌آوره، اما واقعیت اینه که با درک درستش، می‌تونی کدهای خیلی تمیزتر، قابل نگهداری‌تر و مقیاس‌پذیرتری بنویسی. تو این مقاله قراره با هم از صفر شروع کنیم و ببینیم کلاس و شیء توی پایتون دقیقاً چین و چطور می‌تونیم ازشون استفاده کنیم. اگه دنبال بهترین ابزارهای برنامه‌نویسی هستی که کدنویسیت رو ساده‌تر کنن، حتماً یه سر به سایتمون بزن، کلی گجت و اسنیپت باحال داریم که حسابی به دردت می‌خورن!

چرا شیءگرایی (OOP) اینقدر مهمه؟

آموزش کلاس و شیءگرایی در پایتون برای مبتدیان — تصویر 2

تصور کن می‌خوای یه بازی بسازی که توش کلی شخصیت، دشمن و آیتم وجود داره. بدون شیءگرایی، مجبوری برای هر کدوم از اینا کلی متغیر و تابع جدا از هم تعریف کنی. اینجوری بعد یه مدت کدات شلوغ‌پلوغ و غیرقابل مدیریت می‌شن. اینجاست که OOP مثل یه ناجی از راه می‌رسه. شیءگرایی بهت کمک می‌کنه دنیای واقعی رو تو کد شبیه‌سازی کنی. مثلاً هر شخصیت بازی یه “شیء” هست که از یه “کلاس” به اسم “شخصیت” ساخته شده. این کلاس تعریف می‌کنه که یه شخصیت چه ویژگی‌هایی (مثل جون، قدرت، اسم) و چه کارهایی (مثل حرکت کردن، حمله کردن) داره.

  • مدیریت بهتر کد: کدهات منظم‌تر و خواناتر می‌شن.
  • قابلیت استفاده مجدد (Reusability): می‌تونی یه بار کلاس رو تعریف کنی و بارها ازش اشیاء مختلف بسازی.
  • مقیاس‌پذیری: اضافه کردن قابلیت‌های جدید به سیستم راحت‌تر می‌شه.
  • امنیت داده‌ها: می‌تونی کنترل کنی که چه بخشی از داده‌های شیء قابل دسترسی باشه.

مفاهیم اساسی شیءگرایی (OOP) در پایتون

آموزش کلاس و شیءگرایی در پایتون برای مبتدیان — تصویر 3

برای شروع کار با کلاس‌ها و اشیاء، لازمه که با چهار ستون اصلی OOP آشنا بشی. این مفاهیم پایه و اساس هر چیزی هستن که قراره در ادامه یاد بگیریم.

۱. کلاس (Class): نقشه ساخت اشیاء

کلاس رو مثل یه نقشه یا الگو برای ساخت خونه تصور کن. این نقشه مشخص می‌کنه که خونه قراره چند تا اتاق، چند تا پنجره و چه امکاناتی داشته باشه. اما خود نقشه که خونه نیست! تو پایتون هم کلاس یه تعریف کلی از ویژگی‌ها و رفتارهاییه که یه گروه از اشیاء مشترکاً دارن. مثلاً کلاس “ماشین” می‌تونه بگه هر ماشین باید رنگ، مدل و سرعت داشته باشه و بتونه حرکت کنه یا ترمز بگیره.

۲. شیء (Object): خونه ساخته شده از روی نقشه

شیء همون خونه‌ایه که از روی نقشه (کلاس) ساخته شده. یعنی یه نمونه (instance) از اون کلاس. مثلاً از روی کلاس “ماشین” می‌تونی یه شیء به اسم “پراید من” بسازی که رنگش سفید، مدلش ۸۸ و سرعتش ۱۲۰ باشه. هر شیء هویت مستقل خودش رو داره، حتی اگه از یه کلاس مشترک ساخته شده باشه.

۳. خصوصیات (Attributes): ویژگی‌های شیء

خصوصیات یا Attributeها، همون ویژگی‌ها یا داده‌هایی هستن که هر شیء داره. مثلاً برای شیء “پراید من”، خصوصیاتش می‌تونن “رنگ” (سفید)، “مدل” (۸۸) و “سرعت” (۱۲۰) باشن. اینا متغیرهایی هستن که به یه شیء خاص چسبیدن.

۴. متدها (Methods): کارهایی که شیء انجام میده

متدها، توابعی هستن که داخل یک کلاس تعریف می‌شن و روی اشیاء اون کلاس عمل می‌کنن. به عبارت دیگه، متدها همون رفتارهایی هستن که یه شیء می‌تونه از خودش نشون بده. مثلاً برای شیء “پراید من”، متدهاش می‌تونن “حرکت کردن”، “ترمز گرفتن” یا “بوق زدن” باشن. این متدها با دسترسی به خصوصیات شیء، عملیات خاصی رو انجام می‌دن.

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

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

مثال: تعریف یک کلاس ساده

class Car:
    pass # 'pass' یعنی فعلاً هیچی توش نیست

اینجا ما یه کلاس به اسم Car ساختیم. کلمه کلیدی pass هم نشون میده که فعلاً این کلاس هیچ ویژگی یا متدی نداره. حالا چطور یه شیء ازش بسازیم؟

مثال: ساخت یک شیء

my_car = Car() # ساخت یک شیء از کلاس Car
your_car = Car() # ساخت یک شیء دیگر

print(my_car)
print(your_car)

نتیجه چاپ شده آدرس‌های حافظه‌ای متفاوت برای دو شیء نشون میده که هر کدوم از اونا، یه نمونه مجزا از کلاس Car هستن.

متد __init__ و سازنده‌ها

وقتی یه شیء می‌سازی، معمولاً دوست داری یه سری ویژگی‌های اولیه بهش بدی. مثلاً وقتی ماشین رو از کارخونه می‌گیری، رنگ و مدلش از قبل مشخص شده. اینجا متد __init__ (دو آندرلاین قبل و بعد init) به کمکت میاد. این متد رو “سازنده” (Constructor) هم می‌گن چون وقتی یه شیء جدید از کلاس ساخته می‌شه، این متد به‌صورت خودکار فراخونی می‌شه تا شیء رو مقداردهی اولیه کنه.

مثال: کلاس با متد `__init__`

class Car:
    def __init__(self, make, model, color):
        self.make = make      # برند ماشین
        self.model = model    # مدل ماشین
        self.color = color    # رنگ ماشین

# ساخت اشیاء با خصوصیات اولیه
my_car = Car("Toyota", "Camry", "Red")
your_car = Car("Honda", "Civic", "Blue")

print(f"My car is a {my_car.color} {my_car.make} {my_car.model}.")
print(f"Your car is a {your_car.color} {your_car.make} {your_car.model}.")

نکته مهم اینه که اولین پارامتر هر متد در یک کلاس، همیشه self هست. self به خود شیءای اشاره می‌کنه که متد روی اون فراخونی شده. با self.make = make ما خصوصیت make رو به شیء فعلی (یعنی self) اضافه می‌کنیم و مقدارش رو برابر با makeای می‌ذاریم که موقع ساخت شیء به متد __init__ فرستادیم.

متدها و خصوصیات: کارهایی که شیء انجام میده و چیزایی که داره

حالا که ماشین‌های ما خصوصیات دارن، وقتشه بهشون بگیم چه کارهایی می‌تونن انجام بدن. برای این کار، متدها رو اضافه می‌کنیم.

مثال: اضافه کردن متد به کلاس

class Car:
    def __init__(self, make, model, color):
        self.make = make
        self.model = model
        self.color = color
        self.speed = 0 # خصوصیت جدید: سرعت اولیه صفر

    def accelerate(self, increment):
        self.speed += increment
        print(f"The {self.make} {self.model} is now going {self.speed} km/h.")

    def brake(self, decrement):
        self.speed -= decrement
        if self.speed < 0:
            self.speed = 0
        print(f"The {self.make} {self.model} has slowed down to {self.speed} km/h.")

# ساخت یک ماشین
my_car = Car("BMW", "X5", "Black")

# استفاده از متدها
my_car.accelerate(50)
my_car.brake(20)
my_car.accelerate(80)
print(f"Current speed of {my_car.make} {my_car.model}: {my_car.speed} km/h.")

همونطور که می‌بینی، متدهای accelerate و brake به خصوصیت speed دسترسی دارن و اون رو تغییر می‌دن. این قدرت شیءگراییه که داده (خصوصیات) و عملکرد (متدها) رو کنار هم نگه می‌داره.
اگر به دنبال کدهای آماده پایتون برای پروژه‌هات هستی، حتماً بخش اسنیپت‌های پایتون ما رو ببین.

ارث‌بری (Inheritance): قدرت بازاستفاده از کد

یکی از مهم‌ترین و پرکاربردترین مفاهیم OOP، ارث‌بریه. ارث‌بری بهت اجازه می‌ده یک کلاس جدید بسازی که خصوصیات و متدهای یک کلاس دیگه رو به ارث ببره و علاوه بر اون‌ها، ویژگی‌های جدیدی هم داشته باشه. این کار باعث می‌شه از تکرار کد جلوگیری کنی و کدهات رو مرتب‌تر نگه داری. به کلاسی که ازش ارث می‌بریم “کلاس پایه” (Base Class) یا “کلاس والد” (Parent Class) و به کلاس جدید “کلاس مشتق” (Derived Class) یا “کلاس فرزند” (Child Class) می‌گن.

مثال: ارث‌بری

class Vehicle: # کلاس والد
    def __init__(self, make, model):
        self.make = make
        self.model = model
        print(f"Vehicle '{self.make} {self.model}' created.")

    def start_engine(self):
        print(f"Engine of {self.make} {self.model} started.")

class Car(Vehicle): # کلاس فرزند، از Vehicle ارث می‌برد
    def __init__(self, make, model, color):
        super().__init__(make, model) # فراخوانی سازنده کلاس والد
        self.color = color
        print(f"Car '{self.make} {self.model}' (Color: {self.color}) created.")

    def drive(self):
        print(f"The {self.color} {self.make} {self.model} is driving.")

class Bicycle(Vehicle): # کلاس فرزند دیگر
    def __init__(self, make, model, type_bike):
        super().__init__(make, model)
        self.type_bike = type_bike
        print(f"Bicycle '{self.make} {self.model}' (Type: {self.type_bike}) created.")

    def pedal(self):
        print(f"The {self.make} {self.model} (Type: {self.type_bike}) is being pedaled.")

my_car = Car("Tesla", "Model 3", "White")
my_car.start_engine() # متد به ارث برده شده از Vehicle
my_car.drive()      # متد خاص کلاس Car

my_bike = Bicycle("Giant", "Talon", "Mountain")
my_bike.start_engine() # این متد برای دوچرخه معنی ندارد اما از Vehicle به ارث رسیده!
my_bike.pedal()

همونطور که می‌بینی، کلاس Car و Bicycle هر دو از Vehicle ارث بردن. متد super().__init__ رو هم دیدی؟ این دستور به کلاس فرزند اجازه می‌ده سازنده کلاس والد رو فراخونی کنه و خصوصیات مشترک رو مقداردهی اولیه کنه. اینجوری لازم نیست کد make و model رو تو هر کلاس تکرار کنیم.
البته، در مثال Bicycle و متد start_engine()، مشاهده می‌کنی که این متد برای دوچرخه چندان مناسب نیست. اینجاست که مفهوم بازنویسی متد (Method Overriding) و چندریختی به کار میان که در ادامه توضیح میدیم. برای مشاهده کدهای آماده و اسنیپت‌های متنوع در زبان‌های مختلف، از این صفحه بازدید کنید.

چندریختی (Polymorphism): اشکال مختلف یک چیز

“چندریختی” یعنی یه چیز بتونه شکل‌های مختلفی داشته باشه یا به عبارت دیگه، یه متد یکسان، تو کلاس‌های مختلف رفتارهای متفاوتی رو از خودش نشون بده. مثلاً متد move() می‌تونه برای یه ماشین یعنی “حرکت با چرخ”، برای یه پرنده یعنی “پرواز” و برای یه ماهی یعنی “شنا کردن”. همشون “حرکت” می‌کنن، اما به روش‌های متفاوت.

مثال: چندریختی (با بازنویسی متد)

class Vehicle:
    def move(self):
        print("Vehicle moves.")

class Car(Vehicle):
    def move(self): # بازنویسی متد move
        print("Car drives on wheels.")

class Boat(Vehicle):
    def move(self): # بازنویسی متد move
        print("Boat sails on water.")

class Plane(Vehicle):
    def move(self): # بازنویسی متد move
        print("Plane flies in the air.")

# ایجاد یک لیست از وسایل نقلیه مختلف
vehicles = [Car(), Boat(), Plane()]

# هر وسیله نقلیه به روش خودش حرکت می کند
for vehicle in vehicles:
    vehicle.move()

تو این مثال، هر سه کلاس Car، Boat و Plane متد move() رو دارن، اما هر کدوم پیاده‌سازی متفاوتی ازش ارائه می‌دن. اینجوری وقتی یه لیست از Vehicleها داریم و روی هر کدوم متد move() رو صدا می‌زنیم، پایتون به‌طور خودکار نسخه درست اون متد رو بر اساس نوع شیء فراخوانی می‌کنه.

کپسوله‌سازی (Encapsulation) و داده‌های خصوصی

کپسوله‌سازی یعنی جمع کردن داده‌ها (خصوصیات) و متدهایی که روی اون داده‌ها کار می‌کنن، توی یه واحد (کلاس) و مخفی کردن جزئیات داخلی از دنیای بیرون. این کار باعث می‌شه بتونی کنترل کنی که چطور به داده‌های شیء دسترسی پیدا بشه یا تغییر کنن. تو پایتون مفهوم “خصوصی” (private) به اون صورتی که تو زبان‌های دیگه هست، وجود نداره، اما یه سری قرارداد (convention) هست که بهمون کمک می‌کنه این مفهوم رو پیاده‌سازی کنیم.

الف. خصوصیات محافظت‌شده (Protected Attributes) با یک آندرلاین (_)

اگه یه خصوصیت رو با یک آندرلاین _ شروع کنی (مثل _balance)، این فقط یه نشونه‌اس برای برنامه‌نویس‌ها که بگه “هی، اینو مستقیماً تغییر نده، از متدهای کلاس استفاده کن.” پایتون از نظر فنی جلوی دسترسی مستقیم رو نمی‌گیره، اما این یک قرارداد پذیرفته شده در جامعه پایتون هست.

ب. خصوصیات خصوصی (Private Attributes) با دو آندرلاین (__)

اگه یه خصوصیت رو با دو آندرلاین __ شروع کنی (مثل __password)، پایتون یه مقدار شیطنت می‌کنه و اسم اون خصوصیت رو “مخدوش” (name mangling) می‌کنه. یعنی اسمش رو تغییر می‌ده تا دسترسی مستقیم بهش سخت‌تر بشه. البته هنوز هم می‌شه بهش دسترسی پیدا کرد، اما نشون می‌ده که این خصوصیت واقعاً برای استفاده داخلی کلاس طراحی شده.

مثال: کپسوله‌سازی با آندرلاین

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner
        self.__balance = initial_balance # خصوصیت خصوصی

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"Deposited {amount}. New balance: {self.__balance}")
        else:
            print("Deposit amount must be positive.")

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            print(f"Withdrew {amount}. New balance: {self.__balance}")
        else:
            print("Invalid withdrawal amount or insufficient funds.")

    def get_balance(self):
        return self.__balance # متد برای دسترسی کنترل شده به موجودی

my_account = BankAccount("Ali", 1000)
my_account.deposit(500)
my_account.withdraw(200)

# سعی برای دسترسی مستقیم (ناموفق از نظر قرارداد یا منجر به خطا)
# print(my_account.__balance) # AttributeError: 'BankAccount' object has no attribute '__balance'
# print(my_account._BankAccount__balance) # دسترسی غیرمستقیم از طریق Name Mangling

print(f"Current balance for {my_account.owner}: {my_account.get_balance()}")

my_account.withdraw(2000) # برداشت ناموفق

در این مثال، __balance به صورت خصوصی تعریف شده و تنها راه برای تغییر یا خواندنش، استفاده از متدهای deposit، withdraw و get_balance است. این کار باعث می‌شود بتوانیم منطق خاصی برای اعتبارسنجی عملیات (مثلاً چک کردن موجودی قبل از برداشت) اضافه کنیم.

مقایسه برنامه‌نویسی رویه‌ای و شیءگرا

برای اینکه بهتر متوجه بشی شیءگرایی چه مزیتی داره، یه نگاه سریع به تفاوتش با برنامه‌نویسی رویه‌ای (Procedural Programming) بندازیم.

جدول: تفاوت‌های اصلی برنامه‌نویسی رویه‌ای و شیءگرا
ویژگی برنامه‌نویسی رویه‌ای (Procedural) برنامه‌نویسی شیءگرا (OOP)
تمرکز اصلی روی توابع یا “روال‌ها” و دنباله‌ای از دستورات روی “اشیاء” که داده و رفتار را با هم ترکیب می‌کنند
سازماندهی کد بر اساس توابع جداگانه و متغیرهای سراسری بر اساس کلاس‌ها و اشیاء مرتبط
داده‌ها و توابع داده‌ها و توابع جدا از هم هستند داده‌ها و توابع مرتبط با هم در یک شیء کپسوله شده‌اند
قابلیت استفاده مجدد کمتر، معمولاً با کپی کردن یا فراخوانی توابع بالا، از طریق ارث‌بری و چندریختی
پیچیدگی برای پروژه‌های کوچک مناسب، اما در بزرگ‌ترها مشکل‌ساز ممکن است در ابتدا پیچیده‌تر به نظر برسد، اما برای پروژه‌های بزرگ‌تر ایده‌آل است

عیب‌یابی سریع: مشکلات رایج و راه‌حل‌ها

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

مشکل ۱: AttributeError: 'ClassName' object has no attribute 'attribute_name'

شرح: این خطا وقتی پیش میاد که داری به یه خصوصیت دسترسی پیدا می‌کنی که تو کلاس یا اون شیء تعریف نشده.

راه‌حل:

  • اشتباه املایی: مطمئن شو که اسم خصوصیت رو درست نوشتی (به کوچیک و بزرگ بودن حروف دقت کن).
  • مقداردهی اولیه: چک کن که خصوصیت مورد نظر تو متد __init__ یا جای دیگه به درستی به self اضافه شده باشه (مثلاً self.my_attribute = value).
  • اسکوپ (Scope): مطمئن شو که داری از داخل شیء به خصوصیت دسترسی پیدا می‌کنی (مثلاً my_object.attribute_name).

مشکل ۲: متدها پارامتر self را دریافت نمی‌کنند.

شرح: خطاهایی مثل TypeError: my_method() takes 0 positional arguments but 1 was given (وقتی self رو فراموش کردی) یا TypeError: my_method() missing 1 required positional argument: 'self'.

راه‌حل:

  • پارامتر self: همیشه اولین پارامتر هر متدی که داخل کلاس تعریف می‌کنی (به جز متدهای استاتیک و کلاس‌متدها که فعلاً موضوع بحث نیستن) باید self باشه. این پارامتر هنگام فراخوانی متد به‌طور خودکار توسط پایتون پر می‌شه.
  • مثال درست: def my_method(self, arg1, arg2):

مشکل ۳: تغییر خصوصیات یک شیء روی بقیه اشیاء تأثیر می‌گذارد.

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

راه‌حل:

  • مقداردهی در __init__: همیشه خصوصیات قابل تغییر (mutable) مثل لیست‌ها و دیکشنری‌ها رو داخل متد __init__ مقداردهی اولیه کن، نه به عنوان خصوصیت کلاس.
  • مثال درست:
    
    class MyClass:
        def __init__(self):
            self.my_list = [] # هر شیء لیست خودش را دارد
    

پرسش‌های متداول (FAQ)

۱. کلاس و شیء در پایتون چه تفاوتی دارند؟

کلاس مثل یک نقشه یا قالب برای ساخت اشیاء است که ویژگی‌ها (attributes) و رفتارها (methods) را تعریف می‌کند. شیء یک نمونه (instance) واقعی از کلاس است که از روی آن نقشه ساخته شده و دارای مقادیر مشخص برای ویژگی‌هایش است. به عنوان مثال، Car یک کلاس است و my_car = Car("Tesla", "Model 3", "White") یک شیء از کلاس Car است.

۲. متد __init__ چیست و چرا استفاده می‌شود؟

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

۳. منظور از self در متدهای پایتون چیست؟

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

۴. آیا ارث‌بری در پایتون فقط یک کلاس والد را پشتیبانی می‌کند؟

خیر، پایتون از ارث‌بری چندگانه (Multiple Inheritance) پشتیبانی می‌کند. یعنی یک کلاس فرزند می‌تواند از چندین کلاس والد به صورت همزمان ارث ببرد. هرچند، استفاده از ارث‌بری چندگانه می‌تواند به پیچیدگی کد و مسائل مربوط به “الماس مرگ” (Diamond Problem) منجر شود، بنابراین باید با احتیاط و در مواقع ضروری از آن استفاده کرد.

۵. تفاوت بین _attribute و __attribute چیست؟

خصوصیت‌هایی که با یک آندرلاین _ شروع می‌شوند (مانند _name) به صورت “محافظت‌شده” (protected) در نظر گرفته می‌شوند. این یک قرارداد است که نشان می‌دهد این خصوصیت برای استفاده داخلی کلاس یا کلاس‌های فرزند آن در نظر گرفته شده و نباید مستقیماً از بیرون تغییر یابد. خصوصیت‌هایی که با دو آندرلاین __ شروع می‌شوند (مانند __private_data) “خصوصی” (private) نامیده می‌شوند. پایتون اسم این خصوصیت‌ها را به طور داخلی تغییر می‌دهد (name mangling) تا دسترسی مستقیم به آن‌ها از خارج از کلاس دشوارتر شود، هرچند غیرممکن نیست.

خب رفیق، رسیدیم به پایان این سفر هیجان‌انگیز در دنیای کلاس و شیءگرایی در پایتون. امیدوارم که با این توضیحات و مثال‌ها، حسابی با مفاهیم اصلی OOP دوست شده باشی و حالا بتونی کدهای تمیزتر و قدرتمندتری بنویسی. یادگیری شیءگرایی یه جهش بزرگ تو توانایی‌های کدنویسیه، پس تا می‌تونی تمرین کن و کلاس‌های خودت رو بساز. اگه دنبال اسنیپت‌های CSS یا کدهای JavaScript برای پروژه‌های وبت هستی، صفحات مربوطه رو از دست نده. همچنین، برای کمک به ساخت سایتت با اسنیپت‌های وردپرس و قالب‌های HTML می‌تونی از ابزارهای ما استفاده کنی. در نهایت این نکته را فراموش نکنید که هر برنامه‌نویس حرفه‌ای برای افزایش سرعت و کیفیت کارش، به دنبال ابزارهای قدرتمند و بهینه می‌گردد. موفق باشی!

// A simple JS function to handle copy to clipboard for pre blocks
document.addEventListener(‘DOMContentLoaded’, () => {
const copyButtons = document.querySelectorAll(‘button’);
copyButtons.forEach(button => {
if (button.innerText === ‘کپی کد’) {
button.onclick = () => {
const codeBlockId = button.previousElementSibling.id;
const codeContent = document.getElementById(codeBlockId).innerText;
navigator.clipboard.writeText(codeContent).then(() => {
const originalText = button.innerText;
button.innerText = ‘کپی شد!’;
setTimeout(() => {
button.innerText = originalText;
}, 2000);
}).catch(err => {
console.error(‘Failed to copy text: ‘, err);
});
};
}
});
});

Table of Contents

آخرین نوشته‌ها