اذهب إلى المحتوى
  • 0

ما الفرق بين staticmethod و classmethod في أصناف بايثون؟

Adam Ebrahim

السؤال

من فترة تعلمت كيف أقوم بعمل staticmethod في صنف بايثون، والآن وجد كود يحتوي على @classmethod  قبل تعريف دالة في الصنف بنفس طريقة إستعمال staticmethod@  ولم أفهم ما الذي يفعله هذا الأمر.

لذلك أريد أن أعرف ما الفرق بين staticmethod و classmethod في أصناف بايثون؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 2

classmethod@ تجعل التابع تابع صنف أي"class method" وبالتالي تمكننا من الوصول إلى الصنف الذي تم فيه تعريف التابع.
التابع الذي يتم تعريفه على أنه تابع صف، يستقبل كمعامل أول الصف الخاص به ويعبر عن ذلك ب cls، أي بشكل مشابه لما كنا نفعله في التوابع العادية حينما كنا نمرر للتابع العادي نسخة instance أي (self).
إذن هي توابع مرتبطة بالصف وليس بال object.
التوابع المعرفة بهذه الطريقة يكون لديها سماحية "access to the state of the class" أي النفاذ إلى حالة الصف (نحن مررنا لها cls أي أنها تشير إلى الصف نفسه وليس نسخة منه) ويمكنها التعديل عليها أيضاً وهذا التعديل ينتقل إلى كل ال object.
 Static Method@: وهي مشابهة لتلك الموجودة في Java أو C‎+‎+‎.
الدالة  التي نعرفها على أنها ساكة يمكننا الوصول لها من الكلاس نفسه (أي يمكن الوصول لها مباشرة من خلال اسم الكلاس). أو من خلال ال object المأخوذة من الكلاس.
عندما يتم إستدعاء التوابع الساكنة من كائن من هذا الكلاس, فإنه لا تتم معاملته  بشكل خاص بالنسبة للكائن بل سيبقى كأنك تستدعيها بشكل مباشر من الكلاس. وهذا هو السبب في كونها لاتقبل الوسيط self.
التوابع من هذا النوع لاتملك السماحية "access to the state of the class" أي لايمكنها التعديل على حالة الصف. أي أنها لاتعرف شيئ عن حالة الصف class state ولاتستطيع تعديلها أما classmethod يمكنها ذلك.
بشكل عام تستخدم class method كنوع من ال factory method (دوال تعيد object (بشكل مشابه لل constructor ) من أجل استخدام معين أنت تريده) أما ال static فتستخدم كأداة للقيام بعمليات معينة.
إذا لم يكن لديك معرفة عن factory method يمكنك أن تجدها في هذا المقال:  https://wiki.hsoub.com/Design_Patterns/factory_method

from datetime import date
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    # دالة ساكنة لاختبار فيما إذا كان مسناً أم لا
    @staticmethod
    def old(age):
        print("old")
        return age > 55

    #person كلاس ميثود لإنشاء كائن من الصف 
    @classmethod
    def create(cls, name, year):
        return cls(name, date.today().year - year)

print (Person.old(22)) # True
obj=Person.create('km',24)
print(obj)  #  <__main__.Person object at 0x000001C7DC405708>
obj.age # 1997

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

من المعروف أن أي دالة تصف ب statice تكون تنتمي للصنف و ليس لاوبجت من ذلك الصنف بما معناه إننا نستطيع إستدعاء الدالة فقط بكتابة إسم الصنف دون عمل instance منه أي خلق أوبجت كالتالي 

class A(object):
    def foo(self, x):
        print(f"executing foo({self}, {x})")

    @classmethod
    def class_foo(cls, x):
        print(f"executing class_foo({cls}, {x})")

    @staticmethod
    def static_foo(x):
        print(f"executing static_foo({x})")

#هنا نقوم بخلق أوبجكت أو وحده من هذا الصنف 
a = A()

#يمكننا هنا أستدعاء الclassmethod 
#بهذه الطريقة فقط 
a.class_foo(1)

# static_fooأما ال
#فهي تنتمي فقط للكلاس و ليس للأوبجت لذلك يتم أستدعائها من عن طريق إسم الكلاس 
#كالتالي 
A.static_foo('hi')

كما أن الclassmethod تمكنك من تغيير الجالة للأوبجكت الstaticmethod لا تستطيع بها أنم تقوم بتغيير أي حالة و ليس لها علم بأي معلومات عن الأوبجكت 

و كما نرى classmethos تاخذ cls كمتغير يمرر اليها و يجب تمريره أما الstaticmethod فليس شرط أن تأخذ أي متغير 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...