静态方法和类方法

  • 之前,我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息。实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个“正方形”类,通过传入四条边长来构造正方形,并提供计算周长和面积的方法,但是传入的四条边长未必能构造出正方形对象,因此我们可以先写出一个方法来验证四条边长是否可以构成正方形,这个方法很显然就不是对象方法,因为在调用这个方法是正方形对象尚未创建出来(因为都不知道四条边能否构成正方形),所以这个方法是属于正方形类而并不属于正方形对象。我们可以使用静态方法来解决这类问题,代码如下所示: 
1 class Zfx(object):
 2     def __init__(self,a,b,c,d):
 3         self.a = a
 4         self.b = b
 5         self.c = c
 6         self.d = d
 7 #如果类中需要非该类成员存在,则可以使用静态调用的方法@staticmethod
 8     @staticmethod
 9     def is_valid(a,b,c,d):
10         for i in [b,c,d]:
11             if i != a:
12                 return False
13             else:
14                 return True
15     def area(self):
16         if res == True:
17             area_ = self.a * self.b
18             return area_
19         
20 zfx = Zfx(4,4,4,4)
21 res = zfx.is_valid(4,4,4,4)
22 if res ==True:
23     print(zfx.area())
  • 和静态方法比较类似,python还可以在类中定义类方法,类方法的第一个参数约定名为cls,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象,代码如下所示:
1 @classmethod:获取自身类(cls)中的属性,并且可以更改.
 2 classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等
 3 """
 4 from time import time, localtime, sleep
 5 
 6 
 7 class Clock(object):
 8     """数字时钟"""
 9 
10     def __init__(self, hour=0, minute=0, second=0):
11         self._hour = hour
12         self._minute = minute
13         self._second = second
14 
15     @classmethod
16     def now(cls):
17         ctime = localtime(time())
18         return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)
19 
20     def run(self):
21         """走字"""
22         self._second += 1
23         if self._second == 60:
24             self._second = 0
25             self._minute += 1
26             if self._minute == 60:
27                 self._minute = 0
28                 self._hour += 1
29                 if self._hour == 24:
30                     self._hour = 0
31 
32     def show(self):
33         """显示时间"""
34         return '%02d:%02d:%02d' % \
35                (self._hour, self._minute, self._second)
36 
37 
38 def main():
39     # 通过类方法创建对象并获取系统时间
40     clock = Clock.now()
41     while True:
42         print(clock.show())
43         sleep(1)
44         clock.run()
45 
46 
47 if __name__ == '__main__':
48     main()

类和类之间的关系

  • 简单的说,类和类之间的关系有三种:is-a,has-a,use-a关系。
  • is-a关系也叫继承和泛化,比如学生和人的关系、手机和电子产品之间的关系都属于继承关系。
  • has-a关系通常称之为关联,比如部门和员工之间的关系,汽车和引擎的关系都属于关联关系;关联关系如果是整体和部分的关联,那么我们称之为聚合关系;如果整体进一步负责了部分的生命周期(整体和部分是不可分割的,同时存在也同时消亡),那么这种就是最强的关联关系,我们称之为合成关系。
  • use-a关系通常称之为以来,比如司机有一个驾驶的行为(方法),其中(的参数)使用到了汽车,那么司机和汽车的关系就是依赖关系。

继承和多态

  • 可以在已有类的基础上创建新类,这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力,在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,对应的原则称之为里氏替换原则。下面我们先看一个继承的例子。
  • 私有变量和静态函数不可以被继承。
1 #创建一个父类一个子类,父类计算两个数字之和即为Sum,子类打印这个sum
 2 class F(object):
 3     def __init__(self):
 4         self.a = 10
 5         self.b = 20
 6     def Sum(self):
 7         return self.a + self.b
 8 class S(F):
 9     #第一个 __init__是B自身的
10     def __init__(self):
11         F.__init__(self)#super(A,self).__init__()
12     def Print(self):
13         res = self.Sum()
14         print(res)
15 s_ = S()
16 print(s_.a,s_.b)
17 s_.Sum()
  • 子类在继承了父类的方法后,可以对父类已有的方法给出新的实现版本,这个动作称之为方法重写(override)。通过方法重写我们可以让父类的同一个行为在子类中拥有不同的实现版本,当我们调用这个经过子类重写的方法时,不同的子类对象会表现出不同的行为,这个就是多态(poly-morphism)。

装饰器

1 创建一个装饰器,三个函数(两个参数),装饰器处理这两个参数的和,并打印,每一个函数打印这两个参数
 2 """
 3 def deco(func):
 4     def warp(a,b):
 5         c = a + b
 6         print('a+b=',c)
 7         return func(a,b)
 8     return warp
 9 @deco
10 def sum(a,b):
11     print(a,b)
12 sum(1,2)
13 @deco
14 def sum2(a,b):
15     pass
16 sum2(12,23)
1 # 列表生成式
 2 
 3 a = (x for x in range(100000000000) if x % 2== 0)
 4 for i in range(100):
 5     print(next(a))
 6 """
 7 列表生成式
 8 
 9 # 列表生成式
10 
11 a = [x for x in range(100000000000) if x % 2== 0]
12 优点: 计算速度快,因为一次性已经全部加载到内存中了,适合数据量不是太大的情况10000- 2000-
13 缺点: 占用内存
14 
15 # 生成器
16 
17 a = (x for x in range(100000000000) if x % 2== 0)
18 优点: 节约内存空间
19 缺点: 计算速度慢,因为要生成.
20 """
21 import os
22 
23 path = '/Users/joker/jokers/DataSet/stanford-dogs-dataset/Annotation'
24 res = os.listdir(path)
25 print(res)
26 genter = (dir_ for dir_ in res)
27 print(next(genter))
28 
29 # 装饰器
30 
31 def Joker(func):
32 
33     def warp(n1,n2,n3):
34 
35         num = n1 + n2
36 
37         return func(0,num,n3)
38 
39     return warp
40 
41 
42 
43 *装饰器将前两个数字求和,函数本身第三个参数乘上这个和*
44 
45 @Joker
46 
47 def SUM(num1,num2,num3):
48 
49     print(num1,num2,num3)
50 
51     print(num2 * num3)
52 
53 
54 
55 SUM(10,2,3)

函数闭包

  • 引用了自由变量的函数即是一个闭包,这个被引用的自由变量存在,即使已经离开了创造它的环境也不例外

创建python虚拟环境

  • 使用 

conda create -n your_env_name python=X.X(2.7、3.6等)

  •  anaconda 命令创建 python 版本为 X.X、名字为 

your_env_name

  •  的虚拟环境。

your_env_name

  •  文件可以在 Anaconda 安装目录 envs 文件下找到。
  • 打开环境Windows: 

activate your_env_name

  • (虚拟环境名称)
  • 关闭环境Windows: 

deactivate

  • 移除环境conda remove -n yourenvname --all

列表生成式和列表生成器

列表生成式3:计算速度快,占用内存。[ ]

列表生成器:计算速度慢,节约内存空间。( )