c语言基础学python_D07——C语言基础学PYTHON

C语言基础学习PYTHON——基础学习D07

20180826内容纲要:

面向对象进阶学习

1 静态方法

2 类方法

3 属性方法

4 类的特殊成员方法(本节重点)

5 反射(本节重点)

6 异常(本节重点)

7 动态导入模块

8 小结

9 练习

0 类的创建(补充)

1 classFoo(object):2 def __init__(self,name):3 self.name =name4

5 f =Foo("erha")6 print(type(f))7 print(type(Foo))8 #输出结果:

9 #

10 #

11 #发现f的类型是 类__main__.Foo,而Foo的类型是 类,类型

第一种方法

1 #那么我们来看一下类的第二种创建方法

2 deffunc(self):3 print("ni shi sha zi ba")4

5 Foo =type('Foo',(),{'func':func})6 f =Foo()7 f.func()8 print(type(Foo))9 '''

10 #这样看上和第一种有点不一样,因为没有构造函数还没有传参。那怎么操作呢?11

12 def func(self):13 print("%s 今年 %s 岁了"%(self.name,self.age))14

15 def __init__(self,name,age):16 self.name = name17 self.age = age18

19 Foo =type('Foo',(object,),{'func':func,20 '__init__':__init__})21 f =Foo('kanghui',22)22 f.func()

第二种方法

类是由type类实例化产生的。

那么类的创建过程是怎样的呢?类中有一个属性 __metaclass__,其用来表示该类由谁来实例化创建

所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看类创建的过程。

1 #Author:ZhangKanghui

2

3 classMyType(type):4 def __init__(self,what,bases=None,dict=None):5 print("MyType--------init")6 super(MyType,self).__init__(what,bases,dict)7 def __call__(self, *args, **kwargs):8 print("MyType-------call")9 obj = self.__new__(self,*args,**kwargs)10 self.__init__(self,*args,**kwargs)11

12

13 classFoo(object):14 __metaclass__ =MyType15

16 def __init__(self,name):17 self.name =name18 print("Foo-----init")19 def __new__(cls, *args, **kwargs):20 print("Foo----new")21 print(object.__new__(cls)) #通过执行结果们可以看出return的返回值就是Foo的内存地址

22 return object.__new__(cls) #继承父类的new方法

23

24

25 #看不懂没关系,我们先来实例化一下看看都在干吗

26 obj =Foo("erha")27 #执行结果:先执行new再执行init,这是为什么呢?

28 #Foo----new

29 #Foo-----init

30

31 #这个时候我们把new中的return注释掉看一下执行结果。

32 #Foo----new 只执行了new,根本没有实例化。不信可以试一下 print(obj.name)

33 #所以new使用来创建实例的

34 #取消return的注释再执行一下

35 print(obj.name)

__new__&__metaclass

1 静态方法@staticmethod

与类无关,不能访问类里的任何变量

只是名义上归类管理,但实际上静态方法里访问不了类和实例中的任何属性。只是名义上归类管理,但实际上静态方法里访问不了类和实例中的任何属性。

1 #Author:ZhangKanghui

2 #先来大概认识一下staticmethod

3

4 classDog(object):5 def __init__(self,name):6 self.name =name7 @staticmethod #这就跟类没有什么关系了,下面的这个只是一个貌似属于类的函数

8 defeat(self,food):9 print("%s is eating %s" %(self.name,food))10

11 d =Dog("二哈")12 d.eat("baozi")13

14 #正常情况下是可以运行的,但是在eat函数上加一个@staticmethod在运行一下看看

15 #TypeError: eat() missing 1 required positional argument: 'food'

16 #这就跟类没有什么关系了,下面的这个只是一个貌似属于类的函数

静态方法

@staticmethod

通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法

上面的调用会出错误,说是eat需要一个self参数,但调用时却没有传递。

没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。

想让上面的代码可以正常工作有两种办法

1. 调用时主动传递实例本身给eat方法,即d.eat(d)

2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了。这就是静态方法。

1 classDog(object):2 def __init__(self,name):3 self.name =name4

5 @staticmethod6 defeat():7 print("is eating")8 d = Dog("二哈")9 d.eat()

静态方法

@staticmethod

2 类方法  @classmethod

只能访问类变量不能访问实例变量。

如果存在类变量和实例变量相同时,正常情况下会先访问实例变量,然后访问类变量。如果使用类方法则可以强制去访问类变量。

1 #Author:ZhangKanghui

2

3 classDog(object):4 n = "哈士奇"

5 def __init__(self,name):6 self.name =name7 @classmethod #这就跟类没有什么关系了,下面的这个只是一个貌似属于类的函数

8 defeat(self,food):9 #print("%s is eating %s" %(self.name,food))

10 print("%s is eating %s" %(self.n,food))11

12 d =Dog("二哈")13 d.eat("baozi")14 #这样直接运行会报错 AttributeError: type object 'Dog' has no attribute 'name'

15 #此时我们在类下面加一个类变量,然后用self.n调用它

类方法@classmethod

类方法通过@classmethod装饰器实现

此时,定义一个类变量执行以下试试看:

1 classDog(object):2 name = "我是类变量"

3 def __init__(self,name):4 self.name =name5

6 @classmethod7 defeat(self):8 print("%s is eating" %self.name)9

10 d = Dog("二哈")11 d.eat()12

13

14 #执行结果

15

16 我是类变量 is eating

类方法@classmethod

3 属性方法  @property

属性方法的作用就是通过@property把一个方法变成一个静态属性

1 #Author:ZhangKanghui

2 '''

3 class Dog(object):4 def __init__(self,name):5 self.name = name6

7 @property8 def eat(self):9 print("%s is eating %s" %(self.name,"baozi"))10

11 # d =Dog("二哈")12 # d.eat13 #这样就是属性方法,根据运行结果可以发现能够正常运行但是不能传参了14 #那么如果想要传参怎么办呢?15

16 @eat.setter17 def eat(self,food):18 print("set to food:",food)19

20 d =Dog("二哈")21 d.eat22 d.eat ="roubaozi"23 #此时发现虽然给d.eat这个静态方法赋值但是并没有将参数传进去。那怎么做呢?24 '''

25 classDog(object):26 def __init__(self,name):27 self.name =name28 self.__food =None29 @property30 defeat(self):31 print("%s is eating %s" %(self.name,self.__food))32

33 @eat.setter34 defeat(self,food):35 #print("set to food:", food)

36 self.__food =food37

38 @eat.deleter39 defeat(self):40 del self.__food

41 print("删除了吗")42

43 d =Dog("二哈")44 d.eat45 d.eat ="roubaozi"

46 d.eat47

48 #那么属性可以删除吗?

49 #del d.eat 你会发现报错了 删不掉

50 #如果是真的想删除呢? 再加一个@eat.deleter

51 del d.eat

属性方法@property

综上,写一段代码:航班查询

1. 连接航空公司API查询

2. 对查询结果进行解析

3. 返回结果给你的用户

1 #Author:ZhangKanghui

2

3 classFlight(object):4 def __init__(self,name):5 self.flight_name =name6 defchecking_status(self):7 print("checking flight %s status" %self.flight_name)8 return 1

9 defflight_status(self):10 status =self.checking_status()11 if status ==0 :12 print("flight got canceled...")13 elif status == 1:14 print("flight is arrived...")15 elif status == 2:16 print("flight has departured already...")17 else:18 print("cannot confirm the flight status...,please check later")19

20 f = Flight("CA980")21 f.flight_status()

航班查询

变成属性之后能否赋值呢?当然可以改, 不过需要通过@proerty.setter装饰器再装饰一下。

1 classFlight(object):2 def __init__(self,name):3 self.flight_name =name4

5

6 defchecking_status(self):7 print("checking flight %s status" %self.flight_name)8 return 1

9

10

11 @property12 defflight_status(self):13 status =self.checking_status()14 if status ==0 :15 print("flight got canceled...")16 elif status == 1:17 print("flight is arrived...")18 elif status == 2:19 print("flight has departured already...")20 else:21 print("cannot confirm the flight status...,please check later")22

23 @flight_status.setter #修改

24 defflight_status(self,status):25 status_dic ={26 0 : "canceled",27 1 :"arrived",28 2 : "departured"

29 }30 print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )31

32 @flight_status.deleter #删除

33 defflight_status(self):34 print("status got removed...")35

36 f = Flight("CA980")37 f.flight_status38 f.flight_status = 2 #触发@flight_status.setter

39 del f.flight_status #触发@flight_status.deleter

航班查询(改进版)

4 类的特殊成员

a、__doc__ 表示类的描述信息

1 #Author:ZhangKanghui

2

3 classDog(object):4 '''这个类是用来描述哈士奇的'''

5 def __init__(self):6 pass

7

8 print(Dog.__doc__)

__doc__

b、__module__ 表示当前操作对象在那个模块

c、__class__ 表示当前操作对象的类是什么

1 #Author:ZhangKanghui

2

3 classA(object):4 def __init__(self):5 pass

lib

1 #Author:ZhangKanghui

2

3 from lib.empty importA4 obj =A()5 print(obj.__module__)6 print(obj.__class__)7

8 classDog(object):9 def __init__(self,name):10 self.name =name11

12 def __call__(self, *args, **kwargs):13 print("here",args,kwargs)14

15 def __str__(self):16 return (""%self.name)17

18 d =Dog("二哈")19 #这样执行没问题,但是这样呢

20 #d() TypeError: 'Dog' object is not callable 你会发现d后面还能加括号怎么执行呢?

21 d(1,2,3,name='erha')22 #Dog("二哈")(1,2,3,name='erha')

23

24 #print(Dog.__dict__) #打印类的所有属性,不包括实例属性

25 #print(d.__dict__) #打印所有实例属性,不包括类属性

26 print(d)27 '''有没有这些的区别呢?28 def __str__(self):29 return ("" % self.name)30 '''

index

1 lib.empty2

3 here (1, 2, 3) {'name': 'erha'}4

输出结果

d、__init__ 构造方法,通过类创建对象时,自发触发执行。

e、__del__ 析构方法,当对象在内存中被释放时,自发触发执行。

f、__call__ 对象后面加括号触发执行

1 classFoo:2

3 def __init__(self):4 pass

5

6 def __call__(self, *args, **kwargs):7

8 print('__call__')9

10

11 obj = Foo() #执行 __init__

12 obj() #执行 __call__

__call__

g、__dict__ 查看类或对象中的所有成员

1 #Author:ZhangKanghui

2

3 classProvince(object):4 country = 'China'

5

6 def __init__(self,name,count):7 self.name =name8 self.count =count9

10 def func(self,*args,**kwargs):11 print(func)12 #获取类的成员

13 print(Province.__dict__)14 obj =Province("Henan",1000)15 print(obj.__dict__)

__dict__

h、__str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值  改变对象的字符串显示

1 #Author:ZhangKanghui

2 classDog(object):3 def __init__(self,name):4 self.name =name5 self.__food =None6 @property7 defeat(self):8 print("%s is eating %s" %(self.name,self.__food))9 def __str__(self):10 return ""%self.name11 d = Dog("erha")12 print(d)13 #如果直接进行实例化打印输出是个内存地址,此时在实例化钱定义__str__

14 #输出结果分别是:

15 #<__main__.dog object at>

16 #

__str__

i、__getitem__  __setitem__  __delitem__  用于索引操作,如字典。以上分别表示获取、设置和删除数据。

1 #Author:ZhangKanghui

2

3 classFoo(object):4 def __init__(self):5 self.data ={}6

7 def __getitem__(self,key):8 print("__getitem__", key)9 returnself.data.get(key)10 def __setitem__(self, key, value):11 print("__setitem__",key,value)12 self.data[key] =value13

14 def __delitem__(self, key):15 print("__delitem__", key)16

17 obj =Foo()18 #这样实例化之后可以像字典一样给实例赋值

19 obj["name"] ="二哈"

20 print(obj["name"])21 print(obj.data)22 #这个时候的输出是一个字典

23 del obj["name"]24 #输出结果__delitem__ name这个只是执行到这一步但是还没有执行

三合一

5 反射

主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

1 判断object中有没有一个name字符串对应的方法或属性

hasattr(obj,name)

def getattr(object, name, default=None): #known special case of getattr

"""getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.

When a default argument is given, it is returned when the attribute doesn't

exist; without it, an exception is raised in that case."""

pass

getattr(obj,name)

def setattr(x, y, v): #real signature unknown; restored from __doc__

"""Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''"""

pass

setattr(obj,str,val)

def delattr(x, y): #real signature unknown; restored from __doc__

"""Deletes the named attribute from the given object.

delattr(x, 'y') is equivalent to ``del x.y''"""

pass

delattr(obj,str)

看完四个方法的定义之后就来看看实战怎么用?

1 #Author:ZhangKanghui

2

3 defbark(self):4 print("%s is aoaoaoao...."%self.name)5

6 classDog(object):7 def __init__(self,name):8 self.name =name9

10 defeat(self):11 print("%s is eating..." %self.name)12

13 d =Dog("erha")14 choice =input(">>:").strip()15 '''

16 #d.choice #AttributeError: 'Dog' object has no attribute 'choice'17 print(hasattr(d,choice))18 #hasattr(obj,name_str) 判断一个对象obj里是否有对应的name_str字符串方法19 print(getattr(d,choice))20 #getattr(obj,name_str) 根据字符串去获取obj对象里对应方法的内存地址21 getattr(d,choice)()22 '''

23 #那么实际上我们会怎么写呢?

24 ifhasattr(d,choice):25 delattr(d,choice)26 #func = getattr(d, choice)

27 #func("erha")

28 #print(func)

29 #setattr(d,choice,"hashiqi")

30 else:31 '''

32 setattr(d,choice,bark) #d.choice = bark33 #d.bark() TypeError: bark() missing 1 required positional argument: 'self'34 d.talk(d) #在这里,看清楚是talk不是bark 但和d.bark(d)执行结果一样。这就是动态方法35 #为什么talk和bark都是一样的呢?是因为输入的值其实就是choice36 '''

37 #setattr(obj,y,v) is equivalent to x.y=v

38 #这是添加了一个动态方法,那么接下来我们给它加一个动态属性.先把上面注释了

39 setattr(d,choice,None)40 v =getattr(d,choice)41 print( v )42 #方法在返回值时需要加括号,而属性不需要。如果此时我们传入的参数没有,比如age就返回None

43 #但是如果属性存在呢,比如name 那么他会报错,为什么?因为func是一的属性了不能加括号调用,那么把func()注释了呢

44 print(d.name)45

46 #delattr

反射1

1 def delattr(x, y): #real signature unknown; restored from __doc__

2 """

3 Deletes the named attribute from the given object.4

5 delattr(x, 'y') is equivalent to ``del x.y''6 """

7 pass

8 复制代码9

10

11 复制代码12 classBlackMedium:13 feature='Ugly'

14 def __init__(self,name,addr):15 self.name=name16 self.addr=addr17

18 defsell_house(self):19 print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)20 defrent_house(self):21 print('%s 黑中介租房子啦,傻逼才租呢' %self.name)22

23 b1=BlackMedium('万成置地','回龙观天露园')24

25 #检测是否含有某属性

26 print(hasattr(b1,'name'))27 print(hasattr(b1,'sell_house'))28

29 #获取属性

30 n=getattr(b1,'name')31 print(n)32 func=getattr(b1,'rent_house')33 func()34

35 #getattr(b1,'aaaaaaaa') #报错

36 print(getattr(b1,'aaaaaaaa','不存在啊'))37

38 #设置属性

39 setattr(b1,'sb',True)40 setattr(b1,'show_name',lambda self:self.name+'sb')41 print(b1.__dict__)42 print(b1.show_name(b1))43

44 #删除属性

45 delattr(b1,'addr')46 delattr(b1,'show_name')47 delattr(b1,'show_name111')#不存在,则报错

48

49 print(b1.__dict__)

反射2

6 异常

1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x2 IOError 输入/输出异常;基本上是无法打开文件3 ImportError 无法引入模块或包;基本上是路径问题或名称错误4 IndentationError 语法错误(的子类) ;代码没有正确对齐5 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]6 KeyError 试图访问字典里不存在的键7 KeyboardInterrupt Ctrl+C被按下8 NameError 使用一个还未被赋予对象的变量9 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)10 TypeError 传入对象类型与要求的不符合11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,12 导致你以为正在访问它13 ValueError 传入一个调用者不期望的值,即使值的类型是正确的

常用异常

1 ArithmeticError2 AssertionError3 AttributeError4 BaseException5 BufferError6 BytesWarning7 DeprecationWarning8 EnvironmentError9 EOFError10 Exception11 FloatingPointError12 FutureWarning13 GeneratorExit14 ImportError15 ImportWarning16 IndentationError17 IndexError18 IOError19 KeyboardInterrupt20 KeyError21 LookupError22 MemoryError23 NameError24 NotImplementedError25 OSError26 OverflowError27 PendingDeprecationWarning28 ReferenceError29 RuntimeError30 RuntimeWarning31 StandardError32 StopIteration33 SyntaxError34 SyntaxWarning35 SystemError36 SystemExit37 TabError38 TypeError39 UnboundLocalError40 UnicodeDecodeError41 UnicodeEncodeError42 UnicodeError43 UnicodeTranslateError44 UnicodeWarning45 UserWarning46 ValueError47 Warning48 ZeroDivisionError

更多异常

来看看实例:KeyError  IndexError  ValueError

1 #Author:ZhangKanghui

2 '''

3 while True:4 num1 = input('num1:')5 num2 = input('num2:')6

7 try:8 num1 = int(num1)9 num2 = int(num2)10 result = num1 + num211 except Exception as e:12 print('出现异常,信息如下:')13 print(e)14 '''

15 #IndexError

16 dic = ["wupeiqi", 'alex']17 try:18 dic[10]19 exceptIndexError as e:20 print(e)21

22 #KeyError

23 dic = {'k1':'v1'}24 try:25 dic['k20']26 exceptKeyError as e:27 print(e)28

29 #ValueError

30 s1 = 'hello'

31 try:32 int(s1)33 exceptValueError as e:34 print(e)35

36 #万能异常Exception、

37 s1 = 'hello'

38 try:39 int(s1)40 exceptException as e:41 print(e)

实例

1 #Author:ZhangKanghui

2

3 try:4 #open(csv.xml)

5 a = 1

6 print(a)7 except(IndexError,KeyError) as e:8 print("Not Found 404",e)9 exceptValueError as e:10 print("Not Found 101",e)11 exceptException as e:12 print("Unkown Error",e)13

14 else:15 print("No Problem")16

17 finally:18 print("不管有没有错,都会执行")

异常的其他结构

当然,我们也可以自定义异常,通过raise来触发。

1 #Author:ZhangKanghui

2

3 classMiracleException(Exception):4 def __init__(self, msg):5 self.message =msg6 #def __str__(self):

7 #return self.message

8 #上面这两句注释了也不会出问题。

9 #主动出发异常

10 try:11 raise MiracleException('你不能这么做')12 exceptMiracleException as e:13 print(e)

自定义异常

7 动态导入模块

1 #Author:ZhangKanghui

2

3 mod = __import__("lib.empty") #lib

4 #mod = __import__("lib") #这样只能找到lib这一层

5

6 print(mod)7 #

8 print(mod.empty)9 #

10 print(mod.empty.A)11 #

12

13 obj = mod.empty.A("erha")14 print(obj.name)

form module import ...

1 importimportlib2 mod = importlib.import_module("lib.empty") #这个是写到哪一层就是哪一层

3 print(mod)4 print(mod.A)5 print(mod.A("erha"))6 print(mod.A("erha").name)

importlib

此外,还有一个拿来装比的  assert  断言

如果接下来的程序依赖于一个什么条件的情况下可以考虑用断言。这个必须正确才能继续往下进行。

1 importimportlib2 mod = importlib.import_module("lib.empty") #这个是写到哪一层就是哪一层

3 obj = mod.A("erha")4 assert type(obj.name) isstr5 print("我的断言屌不屌")

断言assert

8 小结

感觉自己走进了知识的海洋,然后溺水了!

要学的东西太多了。

慢慢来~厚积薄发

9 练习

其实,没有练习。

但是我还是放一个决策树算法的吧~

1 #Author:ZhangKanghui

2

3 from sklearn.feature_extraction importDictVectorizer4 importcsv5 from sklearn importtree6 from sklearn importpreprocessing7 from sklearn.externals.six importStringIO8

9 #Read in the csv file and put features into list of dict and list of class label

10 allElectronicsData = open(r'/home/zhoumiao/MachineLearning/01decisiontree/AllElectronics.csv', 'rb')11 reader =csv.reader(allElectronicsData)12 headers =reader.next()13

14 print(headers)15

16 featureList =[]17 labelList =[]18

19 for row inreader:20 labelList.append(row[len(row)-1])21 rowDict ={}22 for i in range(1, len(row)-1):23 rowDict[headers[i]] =row[i]24 featureList.append(rowDict)25

26 print(featureList)27

28 #Vetorize features

29 vec =DictVectorizer()30 dummyX =vec.fit_transform(featureList) .toarray()31

32 print("dummyX:" +str(dummyX))33 print(vec.get_feature_names())34

35 print("labelList:" +str(labelList))36

37 #vectorize class labels

38 lb =preprocessing.LabelBinarizer()39 dummyY =lb.fit_transform(labelList)40 print("dummyY:" +str(dummyY))41

42 #Using decision tree for classification

43 #clf = tree.DecisionTreeClassifier()

44 clf = tree.DecisionTreeClassifier(criterion='entropy')45 clf =clf.fit(dummyX, dummyY)46 print("clf:" +str(clf))47

48

49 #Visualize model

50 with open("allElectronicInformationGainOri.dot", 'w') as f:51 f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)52

53 oneRowX =dummyX[0, :]54 print("oneRowX:" +str(oneRowX))55

56 newRowX =oneRowX57 newRowX[0] = 1

58 newRowX[2] =059 print("newRowX:" +str(newRowX))60

61 predictedY =clf.predict(newRowX)62 print("predictedY:" + str(predictedY))

KNN实例应用

使用scikit-learn,需要安装sklearn模块才能用!

我是尾巴~

这次是一个可视化工具:graphviz

转化dot文件至pdf可视化决策树:dot -Tpdf iris.dot -o outpu.pdf

虽不才~才要坚持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值