English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

إضافة خصائص ديناميكية في فئة python وإنشاء أجسام

سيتم حل هذه المشكلة من خلال بعض الجوانب التالية

      1. الوظيفة الرئيسية للبرنامج

      2. عملية التنفيذ

      3. تعريف الفئة

      4. استخدام مولد generator لتحديث كل عنصر ديناميكيًا وإرجاع العنصر

      5. استخدام strip لإزالة الأحرف غير الضرورية

      6. مطابقة السطر

      7. استخدام timestrptime لتحويل النص إلى عنصر وقت

      8. الكود الكامل

الوظيفة الرئيسية للبرنامج

يوجد مستند يحتوي على معلومات المستخدمين يشبه جدولًا: السطر الأول هو الخصائص، وتُفصل الخصائص بفاصلة (،). من السطر الثاني، كل سطر هو قيمة الخاصية الم对应، وكل سطر يمثل مستخدمًا. كيف يمكن تنفيذ قراءة هذا المستند، وعرض كل سطر كعنصر مستخدم؟
إضافة إلى ذلك، هناك 4 متطلبات صغيرة أخرى:

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

يتم فصل كل نص باستخدام المجرد، وقد تكون هناك أقواس مزدوجة (”) أو مزدوجة (') في البداية والنهاية، مثل ”زhang san“، ويجب إزالة الأقواس. إذا كان النص数字، مثل +000000001.24، يجب إزالة المقدمة والنقاط، وإخراج 1.24.

يوجد وقت في الوثيقة، قد يكون في شكل 2013-10-29 أو 2013/10/29 2:23:56، ويجب تحويل هذا النوع من النصوص إلى نوع الوقت.

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

عملية التنفيذ

1. تعريف الكائن

بما أن الخصائص تُضيف بشكل ديناميكي، يتم أيضًا إضافة كل زوج خاصية-قيمة بشكل ديناميكي، لذا يجب أن يحتوي الكائن على دليلاً member functions updateAttributes() وupdatePairs()، بالإضافة إلى استخدام قائمة attributes لتحديد الخصائص، واستخدام قاموس attrilist لتحديد الخرائط. كما أن function init() هي function التركيب. __attributes يحتوي على خط عريض قبل اسم المتغير، مما يعني أن المتغير خاص ولا يمكن استدعاؤه مباشرة من الخارج. يمكن تحقيق الكائن ببساطة باستخدام a=UserInfo() دون الحاجة إلى أي معاملات.

class UserInfo(object):
 'Class to restore UserInformation'
 def __init__ (self):
  self.attrilist={}
  self.__attributes=[]
 def updateAttributes(self,attributes):
  self.__attributes=attributes
 def updatePairs(self,values):
  for i in range(len(values)):
   self.attrilist[self.__attributes[i]]=values[i]

2. تحديث كل كائن ديناميكي باستخدام الجينيراتور (generator) وإرجاع الكائن

الجينيراتور يشبه دالة يمكنها تشغيل نفسها عدة مرات دون الحاجة إلى إعادة التشغيل، ويقوم بإرجاع نتيجة في كل دورة. ومع ذلك، تستخدم الدوال return لإرجاع النتائج، بينما تستخدم الجينيراتور yield لإرجاع النتائج. يتم التشغيل دائمًا عند yield، ويبدأ التشغيل التالي من السطر التالي بعد yield. على سبيل المثال، نحن نحقق في سلسلة فيبوناتشي، ونحقق في كيفية تنفيذها باستخدام الدالة والجينيراتور:

def fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  print(b)
  a, b = b, a + b
  n = n + 1
 return 'done'

نحن نحسب الأرقام الستة الأولى من السلسلة:

>>> fib(6)
1
1
2
3
5
8
'done'

إذا كنت تستخدم الجينيراتور، يمكنك ببساطة تغيير print إلى yield. مثلما في:

def fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  a, b = b, a + b
  n = n + 1

طريقة الاستخدام:

>>> f = fib(6)
>>> f
<جينيراتور كائن fib في 0x104feaaa0>
>>> for i in f:
...  print(i)
... 
1
1
2
3
5
8
>>> 

يمكن رؤية أن الجينيراتور fib هو كائن، ويقوم بوقف العودة بناءً على كل تنفيذ من تنفيذين، ويستمر في تنفيذ السطر التالي بعد yield. يمكن أيضًا تنفيذ الجينيراتور باستخدام generator.next().

في برنامجي، جزء الكود الخاص بالجينرات هو كالتالي:

def ObjectGenerator(maxlinenum):
 filename='/home/thinkit/Documents/usr_info/USER.csv'
 attributes=[]
 linenum=1
 a=UserInfo()
 file=open(filename)
 while linenum < maxlinenum:
  values=[]
  line=str.decode(file.readline(),'gb2312')#linecache.getline(filename, linenum,'gb2312')
  if line=='':
   print'reading fail! Please check filename!'
   break
  str_list=line.split(',')
  for item in str_list:
   item=item.strip()
   item=item.strip('\"')
   item=item.strip('\'')
   item=item.strip('+0*')
   item=catchTime(item)
   if linenum==1:
    attributes.append(item)
   else:
    values.append(item)
  if linenum==1:
   a.updateAttributes(attributes)
  else:
   a.updatePairs(values)
   yield a.attrilist #change to ' a ' to use
  linenum = linenum +1

في برنامجي، جزء الكود الخاص بالجينرات هو كالتالي:

3.استخدام strip لإزالة الأحرف غير الضرورية

من خلال النظر في الكود أعلاه، يمكن رؤية أن باستخدام str.strip(somechar) يمكن إزالة somechar من النص الموجود أمام والخلفي. يمكن أن يكون somechar رمزًا أو نمطًا نصيًا، مثل المثال أعلاه:

item=item.strip()# إزالة جميع الرموز الموجودة أمام والخلفي من النص، مثل\t,\n، وما إلى ذلك
item=item.strip('\"')# إزالة النص الموجود أمام والخلفي
item=item.strip('\'')
item=item.strip('+0*')# إزالة الرقم الموجود أمام النص والخلفي، * يشير إلى عدد من الـ 0 التي يمكن أن تكون متعددة أو لا

4. تطابق re.match النص

نحو الدالة:

re.match(pattern, string, flags=0)

وصف معلمات الدالة:

الوصف للمتغيرات

pattern       النمط النصي الذي سيتم تطابقه

string         النص الذي سيتم تطابقه.

flags          علامات الاستخدام، تستخدم للتحكم في طريقة تطابق النمط النصي، مثل: هل يجب التمييز بين الحروف الكبيرة والصغيرة، التطابق المتعدد الأسطر، وما إلى ذلك.

إذا تم التطابق بنجاح، فإن طريقة re.match تعود بموضوع التطابق، وإلا تعود بلا شيء.`

>>> s='2015-09-18'
>>> matchObj=re.match(r'\d{4}-\d{2}-\d{2}',s, flags= 0)
>>> print matchObj
<_sre.SRE_Match object at 0x7f3525480f38>
1
2
3
4
5

5.استخدام time.strptime لتحويل النص إلى عنصر وقت

في وحدة time، يمكن استخدام time.strptime(str, format) لتحويل str إلى عنصر وقت وفقًا للتنسيق، وتنسيقات الشكل المستخدمة عادةً هي:

     %y 两位数的年份表示(00-99)

     %Y 四位数的年份表示(000-9999)

     %m 月份(01-12)

     %d 月内中的一天(0-31)

     %H 24小时制小时数(0-23)

     %I 12-hour clock hour number (01-12)

     %M minutes (00-59)

     %S seconds (00-59)

In addition, the re module needs to be used to match strings with regular expressions to see if they are in general time formats such as YYYY/MM/DD H:M:S, YYYY-MM-DD, etc.

In the above code, the function catchTime is to determine whether item is a time object, and if it is, it is converted to a time object.

The code is as follows:

import time
import re
def catchTime(item):
 # check if it's time
 matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0)
 if matchObj!= None :
  item =time.strptime(item,'%Y-%m-%d')
  #print "returned time: %s " %item
  return item
 else:
  matchObj=re.match(r'\d{4}/\d{2}/\d{2}\s\d+:\d+:\d+',item,flags=0 )
  if matchObj!= None :
   item =time.strptime(item,'%Y/%m/%d %H:%M:%S')
   #print "returned time: %s " %item
  return item

Complete code:

import collections
import time
import re
class UserInfo(object):
 'Class to restore UserInformation'
 def __init__ (self):
  self.attrilist=collections.OrderedDict()# ordered
  self.__attributes=[]
 def updateAttributes(self,attributes):
  self.__attributes=attributes
 def updatePairs(self,values):
  for i in range(len(values)):
   self.attrilist[self.__attributes[i]]=values[i]
def catchTime(item):
 # check if it's time
 matchObj=re.match(r'\d{4}-\d{2}-\d{2}',item, flags= 0)
 if matchObj!= None :
  item =time.strptime(item,'%Y-%m-%d')
  #print "returned time: %s " %item
  return item
 else:
  matchObj=re.match(r'\d{4}/\d{2}/\d{2}\s\d+:\d+:\d+',item,flags=0 )
  if matchObj!= None :
   item =time.strptime(item,'%Y/%m/%d %H:%M:%S')
   #print "returned time: %s " %item
  return item
def ObjectGenerator(maxlinenum):
 filename='/home/thinkit/Documents/usr_info/USER.csv'
 attributes=[]
 linenum=1
 a=UserInfo()
 file=open(filename)
 while linenum < maxlinenum:
  values=[]
  line=str.decode(file.readline(),'gb2312')#linecache.getline(filename, linenum,'gb2312')
  if line=='':
   print'reading fail! Please check filename!'
   break
  str_list=line.split(',')
  for item in str_list:
   item=item.strip()
   item=item.strip('\"')
   item=item.strip('\'')
   item=item.strip('+0*')
   item=catchTime(item)
   if linenum==1:
    attributes.append(item)
   else:
    values.append(item)
  if linenum==1:
   a.updateAttributes(attributes)
  else:
   a.updatePairs(values)
   yield a.attrilist #change to ' a ' to use
  linenum = linenum +1
if __name__ == '__main__':
 for n in ObjectGenerator(10):
  print n  # عرض المفردات، لتحقق من صحتها

النهاية

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

أعجبك ذلك