python - للاطفال - تحميل كتاب صوتيات اللغة الانجليزية pdf



الحصول على سمات الطبقة (8)

أعلم أن هذا كان قبل ثلاث سنوات ، ولكن بالنسبة لأولئك الذين سيأتون بهذه المسألة في المستقبل ، بالنسبة لي:

class_name.attribute 

يعمل على ما يرام.

https://ffff65535.com

أريد الحصول على صفات الفصل الدراسي ، قل:

class MyClass():
  a = "12"
  b = "34"

  def myfunc(self):
    return self.a

باستخدام MyClass.__dict__ يعطيني قائمة بالسمات والوظائف ، وحتى وظائف مثل __module__ و __doc__ . بينما MyClass().__dict__ فارغًا ما لم MyClass().__dict__ بتعيين قيمة سمة بشكل صريح لذلك المثيل.

أنا فقط أريد السمات ، في المثال أعلاه ستكون تلك: a و b


الحصول على سمات المثيل فقط أمر سهل.
لكن الحصول على صفات الصف دون الوظائف أكثر صعوبة بعض الشيء.

سمات المثيل فقط

إذا كان عليك فقط إدراج سمات المثيلات ، فما عليك سوى استخدام
for attribute, value in my_instance . __dict__ . items()

>>> from __future__ import (absolute_import, division, print_function)
>>> class MyClass(object):
...   def __init__(self):
...     self.a = 2
...     self.b = 3
...   def print_instance_attributes(self):
...     for attribute, value in self.__dict__.items():
...       print(attribute, '=', value)
...
>>> my_instance = MyClass()
>>> my_instance.print_instance_attributes()
a = 2
b = 3
>>> for attribute, value in my_instance.__dict__.items():
...   print(attribute, '=', value)
...
a = 2
b = 3

سمات الطبقة والصف

للحصول على سمات الصف أيضًا بدون الوظائف ، فإن الخدعة هي استخدام callable() .

لكن الطرق الثابتة ليست دائما callable !

لذلك ، بدلاً من استخدام استخدام callable(value)
callable ( getattr ( MyClass, attribute))

مثال

from __future__ import (absolute_import, division, print_function)

class MyClass(object):
   a = "12"
   b = "34"               # class attributes

   def __init__(self, c, d):
     self.c = c
     self.d = d           # instance attributes

   @staticmethod
   def mystatic():        # static method
       return MyClass.b

   def myfunc(self):      # non-static method
     return self.a

   def print_instance_attributes(self):
     print('[instance attributes]')
     for attribute, value in self.__dict__.items():
        print(attribute, '=', value)

   def print_class_attributes(self):
     print('[class attributes]')
     for attribute in MyClass.__dict__.keys():
       if attribute[:2] != '__':
         value = getattr(MyClass, attribute)
         if not callable(value):
           print(attribute, '=', value)

v = MyClass(4,2)
v.print_class_attributes()
v.print_instance_attributes()

ملاحظة: يجب أن تكون @staticmethod print_class_attributes() @staticmethod
لكن ليس في هذا المثال الغبي والبسيط .

نتيجة ل python2

$ python2 ./print_attributes.py
[class attributes]
a = 12
b = 34
[instance attributes]
c = 4
d = 2

نفس النتيجة python3

$ python3 ./print_attributes.py
[class attributes]
b = 34
a = 12
[instance attributes]
c = 4
d = 2

جرب وحدة inspect . يجب أن يكون getmembers والاختبارات المختلفة مفيدة.

تصحيح:

فمثلا،

class MyClass(object):
    a = '12'
    b = '34'
    def myfunc(self):
        return self.a

>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
   'a': '34',
   'b': '12',
   'myfunc': <function __main__.myfunc>}>),
 ('__doc__', None),
 ('__module__', '__main__'),
 ('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
 ('a', '34'),
 ('b', '12')]

الآن ، فإن الطرق والسمات الخاصة تحصل على أعصابي ، يمكن التعامل معها من خلال عدد من الطرق ، وأسهلها هي فقط للتصفية بناءً على الاسم.

>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]

... والأكثر تعقيدًا والتي يمكن أن تتضمن فحوصات خاصة لأسماء الخواص أو حتى أنصاف طبقات ؛)


لا أعرف ما إذا كان هناك شيء مشابه قد تم إجراؤه الآن أم لا ، لكنني قمت بعمل بحث عن خاصية مميزة باستخدام vars (). vars () ينشئ قاموسًا لصفوف الصف الذي تمر به.

class Player():
    def __init__(self):
        self.name = 'Bob'
        self.age = 36
        self.gender = 'Male'

s = vars(Player())
#From this point if you want to print all the attributes, just do print(s)

#If the class has a lot of attributes and you want to be able to pick 1 to see
#run this function
def play():
    ask = input("What Attribute?>: ")
    for key, value in s.items():
        if key == ask:
            print("self.{} = {}".format(key, value))
            break
    else:
        print("Couldn't find an attribute for self.{}".format(ask))

أعمل على تطوير مغامرة نصية ضخمة جدًا في Python ، ولدى فصلى "المشغل" حتى الآن أكثر من 100 سمة. يمكنني استخدام هذا للبحث عن سمات محددة أحتاج إلى رؤيتها.


هناك إجابة بسيطة للغاية ، يجب أن تكون واضحة: getattr

class MyClass(object):
a = '12'
b = '34'
def myfunc(self):
    return self.a

>>> getattr(MyClass, 'a')
'12'

>>> getattr(MyClass, 'myfunc')
<function MyClass.myfunc at 0x10de45378>

انها تعمل داندي على حد سواء في بيثون 2.7 وبيثون 3.x.

إذا كنت تريد قائمة بهذه العناصر ، فستظل بحاجة إلى استخدام الفحص.


يمكنك استخدام dir() في قائمة الاستيعاب للحصول على أسماء السمات:

names = [p for p in dir(myobj) if not p.startswith('_')]

استخدم getattr() للحصول على السمات نفسها:

attrs = [getattr(myobj, p) for p in dir(myobj) if not p.startswith('_')]

myfunc هي سمة من سمات MyClass . هكذا تم العثور عليه عند تشغيل:

myinstance = MyClass()
myinstance.myfunc()

تبحث عن سمة على myinstance تسمى myfunc ، لا تجد واحدة ، ترى أن myinstance هو مثيل MyClass ويبحث عنه في الأعلى.

إذن القائمة الكاملة لسمات MyClass هي:

>>> dir(MyClass)
['__doc__', '__module__', 'a', 'b', 'myfunc']

(لاحظ أني أستخدم dir كطريقة سريعة وسهلة لإدراج أعضاء الصف: يجب استخدامها فقط بطريقة استكشافية ، وليس في رمز الإنتاج)

إذا كنت تريد سمات معينة فقط ، فستحتاج إلى تصفية هذه القائمة باستخدام بعض المعايير ، لأن __doc__ و __module__ و myfunc ليست خاصة بأي شكل من الأشكال ، فهي سمات بالطريقة نفسها تمامًا مثل a و b .

لم أستخدم أبداً وحدة الفحص المشار إليها من قبل Matt و Borealid ، ولكن من رابط موجز يبدو أنه يحتوي على اختبارات لمساعدتك على القيام بذلك ، ولكنك ستحتاج إلى كتابة دالة المسند الخاصة بك ، حيث يبدو أن ما تريده هو تقريبًا الصفات التي لا تمر باختبار isroutine ولا تبدأ وتنتهي isroutine .

لاحظ أيضًا: باستخدام class MyClass(): في Python 2.7 ، فإنك تستخدم فئات قديمة الطراز قديمة للغاية. ما لم تكن تفعل ذلك بشكل متعمد من أجل التوافق مع المكتبات القديمة للغاية ، يجب أن تكون بدلا من ذلك تعريف صفك class MyClass(object): في Python 3 لا توجد فئات "الطراز القديم" ، وهذا السلوك هو الافتراضي. ومع ذلك ، فإن استخدام فئات newstyle سيوفر لك الكثير من السمات المحددة تلقائيًا:

>>> class MyClass(object):
        a = "12"
        b = "34"
        def myfunc(self):
            return self.a
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'myfunc']

def props(cls):   
  return [i for i in cls.__dict__.keys() if i[:1] != '_']

properties = props(MyClass)




python-2.7