在python的类中动态增添属性与变化对象,python动态

正文将透过弹指间多少个方面来一一开展缓和

      1、程序的关键成效

      2、达成进程

      3、类的定义

      4、用生成器generator动态更新各样对象并赶回对象

      5、使用strip 去除不供给的字符

      6、rematch相配字符串

      7、使用timestrptime提取字符串转化为时间对象

      8、完整代码

程序的严重性功能

当今有个存款和储蓄顾客音信的像表格同样的文书档案:第一行是性质,种种属性用逗号(,)分隔,从第二行最初每行是各类属性对应的值,每行代表一个客户。如何落到实处读入那个文书档案,每行输出一个客商对象啊?
金沙国际官网,其他还应该有4个小要求:

每一个文书档案都极大,假若一遍性把具备行生成的那么多目的存成列表再次来到,内部存款和储蓄器会崩溃。程序中年岁至期頣是只能存二个行生成的指标。

用逗号隔开分离的每种字符串,前后恐怕有双引号(”)或许单引号(’),举例”张三“,要把引号去掉;假诺是数字,有+000000001.24那样的,要把前边的+和0都去掉,提抽取1.24

文书档案中不经常光,情势或许是二〇一二-10-29,也或者是二零一一/10/29 2:23:56
那样的款式,要把这么的字符串转成时间档案的次序

那般的文书档案有广大个,每种的属性都不等同,比方那一个是顾客的音信,那么些是通话记录。所以类中的具体性质有怎么样要基于文书档案的首先步履态生成

落到实处过程

1.类的概念

鉴于质量是动态增进的,属性-值
对也是动态增进的,类中要含有updateAttributes()updatePairs()三个分子函数就可以,另外用列表attributes存款和储蓄属性,词典attrilist积累映射。在那之中init()函数为构造函数。
__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'

小编们总括数列的前6个数:

>>> 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
<generator object fib at 0x104feaaa0>
>>> for i in f:
...  print(i)
... 
1
1
2
3
5
8
>>> 

能够看到,生成器fib自身是个对象,每回奉行到yield会中断重回二个结果,后一次又接二连三从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

其中,a=UserInfo()为类UserInfo的实例化.因为文书档案是gb2312编码的,上边运用了相应的解码方法。由于第一行是性质,有个函数将质量列表存入UserInfo中,即updateAttributes();前面包车型大巴行则要将
属性-值 对读入一个字典中贮存。p.s.python中的字典相当于映射(map).

3.运用strip 去除不要求的字符

从地点代码中,能够见见使用str.strip(somechar)就可以去除str前后的somechar字符。somechar能够是符号,也得以是正则表达式,如上:

item=item.strip()#除去字符串前后的所有转义字符,如\t,\n等
item=item.strip('\"')#除去前后的"
item=item.strip('\'')
item=item.strip('+0*')#除去前后的+00...00,*表示0的个数可以任意多,也可以没有

4.re.match相配字符串

函数语法:

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

函数参数表明:

参数           描述

pattern       相称的正则表明式

string         要协作的字符串。

flags         
标识位,用于调控正则表明式的合作方式,如:是不是区分轻重缓急写,多行匹配等等。

若相配成功re.match方法重临几个极其的对象,不然再次来到None。`

>>> 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按照format格式转化为时间对象,format中的常用格式有:

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

     %Y 二位数的年度表示(000-9999)

     %m 月份(01-12)

     %d 月在那之中的一天(0-31)

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

     %I 12时辰制时辰数(01-12)

     %M 分钟数(00=59)

     %S 秒(00-59)

除此以外,还亟需选择re模块,用正则表明式,对字符串举办相配,看是不是是一般时间的格式,如YYYY/MM/DD H:M:S, YYYY-MM-DD

在位置的代码中,函数catchTime正是推断item是不是为时间对象,是的话转化为时间对象。

代码如下:

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

一体化代码:

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  #输出字典,看是否正确

总结

上述便是那篇小说的全体内容,希望能对我们的求学恐怕职业带来一定救助,即便有疑问我们能够留言交换,谢谢大家对帮客之家的支撑。

本文将因而弹指间几个地点来一一进展化解 1、程序的最首要效用 2、完成进度3、类的定义…

动态编制程序语言是高级语言设计的一中项目,常见的动态编制程序语言javascript/php/Ruby,而C/c++/C#则不属于动态语言
概念时不含有有个别品质,运营时累加有些质量

python类和实例动态加多属性和方法,python实例动态增进

from types import  MethodType
# python 是一门动态类型的语言,所以他可以给类和实例动态添加属性和方法
# 但是注意:给实例动态添加的方法只对该实例有效,对其他实例无效
# 但是给类添加的方法对该类生成的实例都有效
class Student(object):
    pass

s=Student()
s.name="zrs"   # 给类添加动态属性
s.age=22
print(s.name)
print(s.age)

def set_age(self,age):
    self.age=age
    return self.age

# 第一个参数是需要添加的方法,第二个参数是实例名
s.set_age=MethodType(set_age,s) # 使用该函数可以给类添加或者实例添加方法
print(s.set_age(25))

def  set_name(self,name):
    self.name=name

# 给类动态添加方法
Student.set_name=set_name
s1=Student()
s1.name="zhognrongshun"
s1.age=22
s1.set_name("666")
print(s1.name)

# 动态语言可以动态添加属性和方法是好事
# 但是有时候必须限制实例添加属性的时候怎么办了?
class  Student2(object):
    __slots__ = ("name","age")  # 在这儿限定只能添加的属性

s11=Student2()
s11.name="zlzl"
s11.age=22
#s11.score=99  #  报错了:'Student2' object has no attribute 'score'
print(s11.name,s11.age)




# 这是给类动态添加方法的第二种方式
#创建一个方法
def set_age(self, arg):
    self.age = arg
#创建一个类
class Student3(object):
    pass
#直接用类来创建一个方法  不过此时还是用链接的方式在类外的内存中创建
Student3.set_age = MethodType(set_age,Student3)
#此时在创建实例的时候外部方法 set_age 也会复制 这些实例和Student3类都指向同一个set_age方法
s21 = Student1()
s21.set_age(60)
print (s21.age)   #看结果

from types import MethodType # python
是一门动态类型的言语,所以他得以给类和实例动态添…

在脚本语言的社会风气里,你能够在运营时随便将别的叁个对象加多二个属性,比方:
obj.MyData = 1;
鬼才知道obj原先有未有MyData属性呢,在剧本引擎实行时,他会为这一个指标动态增加叁个特性MyData,未来你就能够访问它了,何况你供给潜心哦:加多的本性依赖在实例上,并非种类上。
好了,言归正传,在CLENVISION的社会风气中,我们有样的好东东呢?答案是:有!当然有,DL卡宴基于CL帕杰罗编写的,最么恐怕他本人从没呢。
这要感激.net 4新提供的ConditionalWeakTable<TKey,
TValue>类,MSDN是那样解释的:
 
ConditionalWeakTable<TKey, TValue>
类使得语言编写翻译器可在运维时给托管的对象附加大肆属性。ConditionalWeakTable<TKey,
电视alue>
对象是一个字典,它将八个键代表的托管对象绑定到一个值表示的附加属性。该指标的键是
TKey
类的个人实例,属性附加到这么些类上,且其值为分配到对应对象的属性值。
 
稍稍刚强,未有涉及,看代码:

 1 class Person():
 2     def __init__(self, name):
 3         self.name = name
 4 
 5 
 6 def print_name(self):
 7     print(self.name)
 8 
 9 p = Person('Li')
10 import types
11 p.print_name = types.MethodType(print_name, p)    # 绑定函数到对象
12 p.print_name()
13 
14 
15 @staticmethod
16 def print_abc():
17     print('abc')
18 
19 Person.print_abc = print_abc
20 Person.print_abc()
21 
22 
23 @classmethod
24 def print_123(cls):
25     print('123')
26 
27 Person.print_123 = print_123
28 Person.print_123()
1.添加动态属性
class Test(object):
       pass

dir(Test)  # 与dir(object)一样
t=Test()
t.addr=4 # 动态添加实例属性
Test.addr=5 #动态添加类属性
--------------------------------------------------
2.动态添加实例方法
class person(object):
       def __init__(self,name):
              self.name=name
       def eat(self):
            print('%s 正在吃'%name)

def  sleep(self):
     print('%s正在睡觉'%name)

p=Person("wang")
p.sleep=sleep
p.sleep() #报错 ,原因是p的对象虽然指向了def sleep函数,但是p并没有当做sleep方法中的self实参,即缺少参数,故动态添加方法与动态添加属性不是一样的

#正确方法
import  types
p.sleep=types.MethodType(sleep,p)

3.添加静态方法
@staticmethod
      def test():
          print('-----static method')
p.test=test
p.test()
p.xxx=test
p.xxx()

4.添加类方法
 @classmethod
 def   test(cls):
        print('----class method')

p.printmethod=test
p.printmethod()

 

 

一句话来讲:动态向类动态增加类属性,类措施,静态方法操作同样的,直接赋值指向
但加多类实例方法是见仁见智

金沙国际官网 1金沙国际官网 2代码

__ slots__调控类中属性访谈范围
非动态语言访谈类的个性都以在类的概念时就已经鲜明了,python属于动态语言,前期能够动态增添类的性能,可是对类的品质管理就恐怕混乱,slots能很好的主宰实例属性的拜望

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.CompilerServices; 
  
namespace ConditionalWeakTableDemo 

    class Program 
    { 
        static void Main(string[] args) 
        { 
            //演示 为某些对象动态增添属性。 
            object a1 = new object(); 
            object a2 = new object(); 
  
            a1.SetAttachedPropertyValue<string>(“Name”, “a1”); 
            a2.SetAttachedPropertyValue<string>(“Name”, “a2”); 
  
            Console.WriteLine(“(a1)my name is ” + a1.GetAttachedPropertyValue<string>(“Name”)); 
            Console.WriteLine(“(a2)my name is ” + a2.GetAttachedPropertyValue<string>(“Name”)); 
  
            //观望 内部存款和储蓄器变化,看是还是不是有内部存款和储蓄器泄漏 
            for (int i = 0; i < 1000000000; i++) 
            { 
                a1 = new object(); 
                a1.SetAttachedPropertyValue<int>(“Number”, i); 
            } 
        } 
    } 
  
    public static class AttachedProperty 
    { 
        private static ConditionalWeakTable<object, Dictionary<string, object>> _table = 
             new ConditionalWeakTable<object, Dictionary<string, object>>(); 
  
        public static T GetAttachedPropertyValue<T>(this object owner,string propertyName) 
        { 
            Dictionary<string, object> values; 
            if (_table.TryGetValue(owner,out values)) 
            { 
                object temp; 
                if (values.TryGetValue(propertyName,out temp)) 
                { 
                    return (T)temp; 
                } 
            } 
  
            return default(T); 
        } 
  
        public static void SetAttachedPropertyValue<T>(this object owner, string propertyName, T value) 
        { 
            Dictionary<string, object> values; 
            if (!_table.TryGetValue(owner, out values)) 
            { 
                values = new Dictionary<string, object>(); 
                _table.Add(owner, values); 
            } 
  
            values[propertyName] = value; 
        } 
    } 

In [46]: class man(object):
                __slots__=('name')
In [47]: xiaoming=man()
In [48]: xiaoming.name='xiaoming'
In [49]: xiaoming.addr='shenzhen'   #限制实例访问,不能访问该类的实例属性
---------------------------------------------------------------------------
AttributeError     Traceback (most recent call last)
<ipython-input-49-33a40e3d7168> in <module>()
----> 1 xiaoming.addr='shenzhen'     
AttributeError: 'man' object has no attribute 'addr'
In [50]: man.addr='beijing'        #能访问该类的类属性
In [51]: print(xiaoming.addr)
beijing

 

代码不算长,稳重看看就领会了,大家封装了ConditionalWeakTable,那样就足以为任何实例附加贰脾性质了。

 

本来,假如能产生那样就最佳了:

 

dynamic a1 = new Object();
a1.Name = “tansm”;

 

 

 何人能化解?

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图