zoukankan      html  css  js  c++  java
  • Python入门篇-面向对象概述

                 Python入门篇-面向对象概述

                                          作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

    一.语言的分类

    面向机器
      抽象成机器指令,机器容易理解
      代表:汇编语言
    
    面向过程
      做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如果出现了情况B,做什么处理。   问题规模小,可以步骤化,按部就班处理。   代表:C语言
    面向对象OOP
      随着计算机需要解决的问题的规模扩大,情况越来越复杂。需要很多人、很多部门协作,面向过程编程不太适合了。   代表:C
    ++、Java、Python等

    二.面向对象三要素

    1>.什么是面向对象

    什么是面向对象呢?
      一种认识世界、分析世界的方法论。将万事万物抽象为各种对象。
    
    类class 
      类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合。 
      用计算机语言来描述类,是属性和方法的集合。
    
    对象instance、object
      对象是类的具象,是一个实体。 
      对于我们每个人这个个体,都是抽象概念人类的不同的实体。
    
    举例:
      你吃鱼:
        你,就是对象;鱼,也是对象;吃就是动作
        你是具体的人,是具体的对象。你属于人类,人类是个抽象的概念,是无数具体的人的个体的抽象。
        鱼,也是具体的对象,就是你吃的这一条具体的鱼。这条鱼属于鱼类,鱼类是无数的鱼抽象出来的概念。
        吃,是动作,也是操作,也是方法,这个吃是你的动作,也就是人类具有的方法。如果反过来,鱼吃人。吃就是鱼类的动作了。
        吃,这个动作,很多动物都具有的动作,人类和鱼类都属于动物类,而动物类是抽象的概念,是动物都有吃的动作,但是吃法不同而已。
      你驾驶车:
        这个车也是车类的具体的对象(实例),驾驶这个动作是鱼类不具有的,是人类具有的方法。
    
    属性:
      它是对象状态的抽象,用数据结构来描述。
    
    操作:
      它是对象行为的抽象,用操作名和实现该操作的方法来描述。
      每个人都是人类的一个单独的实例,都有自己的名字、身高、体重等信息,这些信息是个人的属性,但是,这些信息不能保存在人类中,因为它是抽象的概念,不能保留具体的值。
      而人类的实例,是具体的人,他可以存储这些具体的属性,而且可以不同人有不同的属性。
    
    哲学
      一切皆对象
      对象是数据和操作的封装 对象是独立的,但是对象之间可以相互作用。 
      目前OOP是最接近人类认知的编程范式。

    2>.面向对象三要素

    封装
      组装:将数据和操作组装到一起。
      隐藏数据:对外只暴露一些接口,通过接口访问对象。比如驾驶员使用汽车,不需要了解汽车的构造细节,只需要知道使用什么部件怎么驾驶就行,踩了油门就能跑,可以不了解其中的机动原理。
      博主推荐阅读:https://www.cnblogs.com/yinzhengjie/p/11161519.html

    继承   多复用,继承来的就不用自己写了
      多继承少修改,OCP(Open
    -closed Principle),使用继承来改变,来体现个性
      博主推荐阅读:https://www.cnblogs.com/yinzhengjie/p/11173836.html

    多态   面向对象编程最灵活的地方,动态绑定   博主推荐阅读:https://www.cnblogs.com/yinzhengjie/p/11179289.html

    举例:
      人类就是封装;
      人类继承自动物类,孩子继承父母特征。分为单一继承、多继承;
      多态,继承自动物类的人类、猫类的操作”吃“不同。

    三.Python的类

    1>.Python类定义格式

    class ClassName:
        语句块。
    
    Python类定义格式如上所示,我们需要注意以下几点:
        1. 必须使用class关键字
        2. 类名必须是用大驼峰,本质上就是一个标识符
        3. 类定义完成后,就产生了一个类对象,绑定到了标识符ClassName上

    2>.类对象及类属性

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class MyClass:
     7     """ A Example Class."""
     8     CLASSNAME = "bigdata & devops"      #类属性,也可以称之为类的变量。需要注意它和实例变量的区别。实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法。一般来说,类变量可使用全大写来命名。即表示常量。
     9 
    10     """
    11         1>.通常,每次实例化后获得的实例,是不同的实例,即使是使用同样的参数实例化,也得到不一样的对象。和Java语法类似,Python类实例化过程中,
    12     首先会调用new方法进行实例化(可以理解为创建出对象),然后会自动调用 __init__ 方法(可以理解为对已经创建出的对象进行初厂设置)。这个方法第
    13     一个形式参数必须留给self,其它形式参数随意。
    14         2>.该方法可以不定义,如果定义会在实例化后隐式调用。它的作用就是对实例进行初始化。 
    15         3>.该方法不能有返回值,也就是只能return None。
    16     """
    17     def __init__(self,name:str,age:int):
    18         """
    19             我们知道self表示的是当前实例对象,我们这里为当前实例绑定2个实例变量(即name和age),它并不属于类属性,它属于实例对象。
    20         """
    21         self.name = name
    22         self.age = age
    23 
    24     """
    25         类的普通方法(method),也是类属性。本质上就是普通的函数对象function,它一般要求至少有一个参数。第一个形式参数可以是self(self只是个
    26     惯用标识符,可以换名字),这个参数位置就留给了self。它指代当前实例本身。
    27         类实例化后,得到一个实例对象,实例对象会绑定到方法上,即会把方法的调用者实例作为第一参数self的实参传入。
    28     """
    29     def showme(self):             #
    30         return self.name
    31 
    32 
    33 print(MyClass)                     #不会调用"__init__"方法,因为咱们没有对MyClass类进行实例化操作。
    34 print(MyClass.showme)
    35 print(MyClass.__doc__)             #注意,这里的"__doc__"也是类的特殊属性。
    36 print(MyClass.__name__)            #对象名
    37 print(MyClass.__class__)           #对象的类型
    38 print(MyClass.__dict__)            #对象的属性字典
    39 print(MyClass.__qualname__)        #类的限定名
    40 
    41 print("{0} {1} {0}".format("*"*10,"注意:Python中每一种对象都拥有不同的属性。函数是对象,类是对象,类的实例也是对象。"))
    42 
    43 s1 = MyClass("Jason",18)           #实例化过程中会自动调用"__init__"方法进行初始化操作,然后类实例化后一定会获得一个类的实例,它就是实例对象s1。
    44 print(s1.showme())                 #s1是Myclass类实例化后得到的一个实例对象,实例对象会绑定到方法上,因此我们这里就不需要为 showme(self)方法传参,直接调用即可,如果有2个或以上参数那调用时除了第一个参数不需要传递外,其他参数依旧是要传入的哟。
    45 print(s1.__dict__)
    46 
    47 
    48 
    49 
    50 #以上代码输出结果如下:
    51 <class '__main__.MyClass'>
    52 <function MyClass.showme at 0x10215fae8>
    53  A Example Class.
    54 MyClass
    55 <class 'type'>
    56 {'__module__': '__main__', '__doc__': ' A Example Class.', 'CLASSNAME': 'bigdata & devops', '__init__': <function MyClass.__init__ at 0x10215f950>, 'showme': <function MyClass.showme at 0x10215fae8>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>}
    57 MyClass
    58 ********** 注意:Python中每一种对象都拥有不同的属性。函数是对象,类是对象,类的实例也是对象。 **********
    59 Jason
    60 {'name': 'Jason', 'age': 18}

    3>.实例属性的查找顺序 

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7 总结
     8     是类的,也是这个类所有实例的,其实例都可以访问到;
     9     是实例的,就是这个实例自己的,通过类访问不到。
    10     类变量是属于类的变量,这个类的所有实例可以共享这个变量。
    11     对象(实例或类)可以动态的给自己增加一个属性(赋值即定义一个新属性)。
    12     实例.__dict__[变量名] 和 实例.变量名 都可以访问到实例自己的属性(注意这两种访问是有本质区别的)。 实例的同名变量会隐藏掉类变量,或者说是覆盖了这个类变量。但是注意类变量还在那里,并没有真正被覆盖。
    13 
    14 实例属性的查找顺序
    15     指的是实例使用 .点号 来访问属性,会先找自己的 __dict__ ,如果没有,然后通过属性 __class__ 找到自己的类,再去类的 __dict__ 中找
    16     注意:如果实例使用 __dict__[变量名] 访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key 查找,不是属性查找。
    17 """
    18 
    19 class Person:
    20     age = 3         #一般来说,类变量可使用全大写来命名。我们这里为了实验效果,故意将类变量和实例变量命令部分重复以达到测试目的。
    21     height = 170
    22 
    23     def __init__(self,name,age=18):
    24         self.name = name
    25         self.age = age
    26 
    27 
    28 tom = Person("Tom")
    29 jason = Person("Jason",20)
    30 
    31 Person.age = 30
    32 print(1,Person.age,tom.age,jason.age)
    33 print(2,Person.height,tom.height,jason.height)
    34 
    35 jason.height = 175      #动态为jason对象设置"height"属性
    36 print(3,Person.height,tom.height,jason.height)
    37 
    38 tom.height += 10        #其实等价于tom.height = tom.height + 10,由于tom的"__dict__"没有"height"属性,因此它会去Person类的"__dict__中找"
    39 print(4,Person.height,tom.height,jason.height)
    40 
    41 Person.height += 15
    42 print(5,Person.height,tom.height,jason.height)
    43 
    44 Person.weight = 70
    45 print(6,Person.weight,tom.weight,jason.weight)
    46 
    47 print(7,Person.__dict__)
    48 print(8,tom.__dict__)
    49 print(9,jason.__dict__)
    50 
    51 print(10,tom.__dict__["height"])
    52 # print(11,tom.__dict__["weight"])      #会抛出"KeyError: 'weight'"异常!
    53 
    54 
    55 
    56 #以上代码输出结果如下:
    57 1 30 18 20
    58 2 170 170 170
    59 3 170 170 175
    60 4 170 180 175
    61 5 185 180 175
    62 6 70 70 70
    63 7 {'__module__': '__main__', 'age': 30, 'height': 185, '__init__': <function Person.__init__ at 0x10205fae8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'weight': 70}
    64 8 {'name': 'Tom', 'age': 18, 'height': 180}
    65 9 {'name': 'Jason', 'age': 20, 'height': 175}
    66 10 180

    四.装饰一个类(即类装饰器)

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7     需求,为一个类通过装饰,增加一些类属性。例如能否给一个类增加一个NAME类属性并提供属性值.
     8 """
     9 def add_name(name):
    10     def wrapper(cls):
    11         cls.NAME = name
    12         return cls
    13     return wrapper
    14 
    15 @add_name("Jason")
    16 class Person:
    17     AGE = 18
    18 
    19 print(Person.NAME)      #之所以能够装饰,本质上是为类对象动态的添加了一个属性,而Person这个标识符指向这个类对象。
    20 
    21 
    22 
    23 #以上代码输出结果如下:
    24 Jason

    五.类方法和静态方法

    1>.普通函数(最好禁止在类中定义无参函数)

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class Person:
     7     def __init__(self,name,age):
     8         self.name = name
     9         self.age = age
    10 
    11     def normal_method():    #注意:在Python中虽然语法是对的,但是,没有人这么用,也就是说禁止这么写
    12         print("normal")
    13 
    14 
    15 Person.normal_method()      #可以放在类中定义,因为这个方法只是被Person这个名词空间管理的一个普通的方法,normal_method是Person 的一个属性而已。类是可以调用的,但该类的实例不能调用该方法。
    16 
    17 p1 = Person("Jason",18)
    18 
    19 # p1.normal_method()       #由于normal_method在定义的时候没有指定形参self,所以不能完成实例对象的绑定,因此p1实例不能调用。只要一调用就会为normal_method传递一个self参数,而原方法是一个无参函数。只要一调用该方法就报错!!!

    2>.类方法 

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class Person:
     7     def __init__(self,name,age):
     8         self.name = name
     9         self.age = age
    10 
    11     """
    12     类方法:(类似于C++、Java中的静态方法)
    13         1>.在类定义中,使用@classmethod装饰器修饰的方法 
    14         2>.必须至少有一个参数,且第一个参数留给了cls,cls指代调用者即类对象自身 
    15         3>.cls这个标识符可以是任意合法名称,但是为了易读,请不要修改
    16         4>.通过cls可以直接操作类的属性
    17 
    18     注意:无法通过cls操作类的实例。为什么?
    19     """
    20     @classmethod
    21     def class_method(cls):
    22         print("class = {0.__name__} ({0})".format(cls))
    23         print("class = {0.__dict__} ({0})".format(cls))
    24 
    25 
    26 Person.class_method()           #使用类对象直接调用类方法,访问的是类的属性
    27 
    28 jason = Person("Jason",18)
    29 jason.class_method()            #使用类的实例化对象调用类方法,访问的还是类的属性
    30 
    31 
    32 
    33 #以上代码输出结果如下:
    34 class = Person (<class '__main__.Person'>)
    35 class = {'__module__': '__main__', '__init__': <function Person.__init__ at 0x10215fae8>, 'class_method': <classmethod object at 0x1005aea58>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} (<class '__main__.Person'>)
    36 class = Person (<class '__main__.Person'>)
    37 class = {'__module__': '__main__', '__init__': <function Person.__init__ at 0x10215fae8>, 'class_method': <classmethod object at 0x1005aea58>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} (<class '__main__.Person'>)

    3>.静态方法

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class Person:
     7     def __init__(self,name,age):
     8         self.name = name
     9         self.age = age
    10 
    11     @classmethod
    12     def class_method(cls):
    13         print("class = {0.__name__} ({0})".format(cls))
    14         cls.HEIGHT = 170
    15     """
    16     静态方法
    17         1>.在类定义中,使用@staticmethod装饰器修饰的方法
    18         2>.调用时,不会隐式的传入参数
    19         静态方法,只是表明这个方法属于这个名词空间。函数归在一起,方便组织管理。
    20     """
    21     @staticmethod
    22     def static_methd(cls):
    23         print(Person.HEIGHT)
    24 
    25 Person.class_method()
    26 
    27 jason = Person("Jason",18)
    28 
    29 Person.static_methd(jason)          #使用类对象调用静态方法时,需要手动传入参数。
    30 
    31 print(Person.__dict__)
    32 print(jason.__dict__)
    33 
    34 #以上代码执行结果如下:
    35 class = Person (<class '__main__.Person'>)
    36 170
    37 {'__module__': '__main__', '__init__': <function Person.__init__ at 0x10205fae8>, 'class_method': <classmethod object at 0x102061208>, 'static_methd': <staticmethod object at 0x102061080>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'HEIGHT': 170}
    38 {'name': 'Jason', 'age': 18}

    4>.方法的调用

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7     类可以定义这么多种方法,究竟如何调用它们?
     8     总结:
     9         类除了普通方法都可以调用,普通方法需要类对象的实例作为第一参数。
    10         实例可以调用所有类中定义的方法(包括类方法、静态方法),普通方法传入实例自身,静态方法和类方法需要找到实例的类(因为实例"__dict__"中没有
    11     静态方法和类方法属性,他得去实例的类中"__dict__"的去查找想要的属性)。
    12 """
    13 
    14 
    15 class Person:
    16     """
    17         我们称没有用"classmethod"或"staticmethod"装饰器修饰的方法为普通方法。
    18         类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一参数必须是类的实例。
    19         实例也几乎可以调用所有的方法, 普通的函数的调用一般不可能出现,因为原则上不允许这么定义。
    20     """
    21     def method(self):
    22         print("{}'s method".format(self))
    23 
    24     @classmethod
    25     def class_method(cls):  # cls是什么
    26         print('class = {0.__name__} ({0})'.format(cls))
    27         cls.HEIGHT = 170
    28 
    29     @staticmethod
    30     def static_methd():
    31         print(Person.HEIGHT)
    32 
    33 print("{0} {1} {0}".format("*"*10,"类访问"))
    34 #print(1, Person.method())           #会抛出异常,因为咱们类调用普通方法需要手动传参数,而实例调用由于做了实例绑定,因此实例调用则不需要传参数哟。
    35 print(2, Person.class_method())
    36 print(3, Person.static_methd())
    37 
    38 
    39 
    40 print("{0} {1} {0}".format("*"*10,"jason实例访问"))
    41 jason = Person()
    42 print(4, jason.method())
    43 print(5, jason.class_method())
    44 print(6, jason.static_methd())
    45 
    46 print("{0} {1} {0}".format("*"*10,"对比类对象和类实例对象"))
    47 print(7,"Person:{}	 Person实例:{}	".format(Person.method,jason.method))         #我们可以通过打印Person和Person实例的普通方法地址就可以看出点端倪,实例对象被普通方法做了实例绑定。
    48 print(8,Person.__dict__)
    49 print(9,jason.__dict__)
    50 
    51 
    52 #以上代码输出结果如下:
    53 ********** 类访问 **********
    54 class = Person (<class '__main__.Person'>)
    55 2 None
    56 170
    57 3 None
    58 ********** jason实例访问 **********
    59 <__main__.Person object at 0x102961208>'s method
    60 4 None
    61 class = Person (<class '__main__.Person'>)
    62 5 None
    63 170
    64 6 None
    65 ********** 对比类对象和类实例对象 **********
    66 7 Person:<function Person.method at 0x10295fae8>     Person实例:<bound method Person.method of <__main__.Person object at 0x102961208>>    
    67 8 {'__module__': '__main__', '__doc__': '
            我们称没有用"classmethod"或"staticmethod"装饰器修饰的方法为普通方法。
            类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一参数必须是类的实例。
            实例也几乎可以调用所有的方法, 普通的函数的调用一般不可能出现,因为原则上不允许这么定义。
        ', 'method': <function Person.method at 0x10295fae8>, 'class_method': <classmethod object at 0x102907be0>, 'static_methd': <staticmethod object at 0x10294ff60>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, 'HEIGHT': 170}
    68 9 {}

    六.小试牛刀

    1>.机整数生成类 

      可以先设定一批生成数字的个数,可设定指定生成的数值的范围。运行时还可以调整每批生成数字的个数
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self.count = count
    13 
    14     def generate(self):
    15         return [random.randint(self.start,self.stop) for i in range(self.count)]
    16 
    17 
    18 print(RandomGen().generate())
    19 print(RandomGen(200,1000,5).generate())
    20 
    21 
    22 
    23 #以上代码执行结果如下:
    24 [25, 32, 14, 7, 15, 94, 41, 68, 85, 58]
    25 [715, 428, 920, 954, 217]
    参考一:普通类实现
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9 
    10     @classmethod
    11     def generate(cls,start=1,stop=100,count=10):
    12         return [random.randint(start,stop) for i in range(count)]
    13 
    14 
    15 print(RandomGen().generate())
    16 print(RandomGen().generate(200,1000,5))
    17 
    18 
    19 
    20 #以上代码执行结果如下:
    21 [19, 21, 89, 86, 65, 58, 94, 29, 76, 71]
    22 [461, 392, 229, 732, 575]
    参考二:作为工具类来实现,提供类方法
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self.count = count
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:
    17             yield random.randint(self.start,self.stop)
    18 
    19     def generate(self):
    20         return [next(self._gen) for i in range(self.count)]
    21 
    22 
    23 print(RandomGen().generate())
    24 print(RandomGen(200,1000,5).generate())
    25 
    26 
    27 
    28 #以上代码执行结果如下:
    29 [96, 15, 55, 87, 43, 21, 100, 55, 96, 81]
    30 [501, 208, 657, 806, 499]
    参考三:生成器实现
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self.count = count
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:
    17             yield random.randint(self.start,self.stop)
    18 
    19     def generate(self):
    20         yield from (next(self._gen) for i in range(self.count))
    21 
    22 
    23 print(list(RandomGen().generate()))
    24 print(list(RandomGen(200,400,5).generate()))
    25 
    26 
    27 #以上代码执行结果如下:
    28 [51, 25, 94, 2, 16, 75, 9, 20, 2, 21]
    29 [285, 211, 249, 271, 309]
    参考四:生成器变形一
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self.count = count
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:
    17             yield random.randint(self.start,self.stop)
    18 
    19     def generate(self,count=0):             #可以后期在产生数据时控制个数。
    20         count = self.count if count <= 0 else count
    21         return [next(self._gen) for i in range(count)]
    22 
    23 
    24 print(RandomGen().generate())
    25 print(RandomGen(600,900).generate(5))
    26 
    27 
    28 #以上代码执行结果如下:
    29 [36, 84, 45, 26, 32, 91, 42, 75, 49, 36]
    30 [647, 885, 642, 857, 852]
    参考五:生成器变形二
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self._count = count      #保护变量
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:     #一次yield一批
    17             yield [random.randint(self.start,self.stop) for _ in range(self._count)]
    18 
    19     def generate(self,count=0):             #可以后期在产生数据时控制个数。
    20         if count > 0:
    21             self._count = count
    22         return next(self._gen)
    23 
    24 print(RandomGen().generate())
    25 print(RandomGen(1000,2000).generate(5))
    26 
    27 
    28 #以上代码执行结果如下:
    29 [51, 20, 52, 31, 64, 47, 43, 75, 47, 98]
    30 [1606, 1570, 1063, 1842, 1427]
    参考六:生成器变形三
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self._count = count      #保护变量
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:     #一次yield一批
    17             yield [random.randint(self.start,self.stop) for _ in range(self._count)]
    18 
    19     def generate(self):
    20         return next(self._gen)
    21 
    22     @property
    23     def count(self):
    24         return self._count
    25 
    26     @count.setter
    27     def count(self,count):
    28         self._count = count
    29 
    30 r = RandomGen(100,200)
    31 print(r.count)
    32 print(r.generate())
    33 
    34 r.count = 5
    35 print(r.count)
    36 print(r.generate())
    37 
    38 
    39 #以上代码执行结果如下:
    40 10
    41 [130, 188, 174, 127, 180, 144, 189, 105, 146, 119]
    42 5
    43 [157, 145, 168, 131, 105]
    参考七:使用property属性装饰器实现

    2>.打印坐标 

      使用上题中的类,随机生成20个数字,两两配对形成二维坐标系的坐标,把这些坐标组织起来,并打印输出
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 import random
     7 
     8 class RandomGen:
     9     def __init__(self,start=1,stop=100,count=10):
    10         self.start = start
    11         self.stop = stop
    12         self._count = count      #保护变量
    13         self._gen = self._generate()
    14 
    15     def _generate(self):
    16         while True:     #一次yield一批
    17             yield [random.randint(self.start,self.stop) for _ in range(self._count)]
    18 
    19     def generate(self):
    20         return next(self._gen)
    21 
    22     @property
    23     def count(self):
    24         return self._count
    25 
    26     @count.setter
    27     def count(self,count):
    28         self._count = count
    29 
    30 class Point:
    31     def __init__(self,x,y):
    32         self.x = x
    33         self.y = y
    34 
    35 r = RandomGen()
    36 points = [Point(x,y) for x,y in zip(r.generate(),r.generate())]
    37 
    38 for p in points:
    39     print("{:2}:{:2}".format(p.x,p.y))
    40 
    41 
    42 #以上代码执行结果如下:
    43 44: 1
    44 66:59
    45 40: 3
    46 92:73
    47 90:73
    48 22:67
    49 98:47
    50 82:10
    51 17:69
    52 36:39
    参考案例

    3>.车辆信息 

      记录车的品牌mark、颜色color、价格price、速度speed等特征,并实现车辆管理,能增加车辆、显示全部车辆的信息功能
     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class Car:
     7     def __init__(self,mark,speed,color,price):
     8         self.mark = mark
     9         self.speed = speed
    10         self.color = color
    11         self.price = price
    12 
    13 
    14 class CarInfo:
    15     def __init__(self):
    16         self.__info = []
    17 
    18     def addcar(self,car:Car):
    19         self.__info.append(car)
    20 
    21     def getall(self):
    22         return self.__info
    23 
    24 
    25 ci = CarInfo()
    26 car = Car('audi',400,'red',100)
    27 ci.addcar(car)
    28 
    29 
    30 ci.getall()         #返回所有数据,此时再实现格式打印
    参考案例

    4>.实现温度的处理 

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 class Temperature:
     7     def __init__(self,t,unit='c'):
     8         self._c = None
     9         self._f = None
    10         self._k = None
    11 
    12         #都要先转换到摄氏度,以后访问再计算其它单位的温度值
    13         if unit == 'f':
    14             self._f = t
    15             self._c = self.f2c(t)
    16         elif unit == 'k':
    17             self._k = t
    18             self._c = self.k2c(t)
    19         else:
    20             self._c = t
    21 
    22     @property
    23     def c(self):
    24         return self._c
    25 
    26     @property
    27     def f(self):        #华氏温度
    28         if self._f is None:
    29             self._f = self.c2f(self._c)
    30         return self._f
    31 
    32     @property
    33     def k(self):        #开氏温度
    34         if self._k is None:
    35             self._k = self.c2k(self._c)
    36         return self._k
    37 
    38     @classmethod
    39     def c2f(cls,c):
    40         return 9 * c / 5 + 32
    41 
    42     @classmethod
    43     def f2c(cls,f):
    44         return (f - 32 ) * 5 / 9
    45 
    46     @classmethod
    47     def c2k(cls,c):
    48         return c + 273.15
    49 
    50     @classmethod
    51     def k2c(cls,k):
    52         return k - 273.15
    53 
    54     @classmethod
    55     def f2k(cls,f):
    56         return cls.c2k(cls.f2c(f))
    57 
    58     @classmethod
    59     def k2f(cls,k):
    60         return cls.c2f(cls.k2c(k))
    61 
    62 print(Temperature.c2f(30))
    63 print(Temperature.f2c(108))
    64 print(Temperature.c2k(30))
    65 print(Temperature.k2c(520.13))
    66 print(Temperature.f2k(108))
    67 print(Temperature.k2f(520.13))
    68 
    69 print("{0} 我是分割线 {0}".format("*" * 20))
    70 
    71 
    72 t = Temperature(108,'f')
    73 print(t.__dict__)
    74 print(t.c,t.k,t.f)
    75 print(t.__dict__)
    76 
    77 
    78 
    79 #以上代码执行结果如下:
    80 86.0
    81 42.22222222222222
    82 303.15
    83 246.98000000000002
    84 315.3722222222222
    85 476.564
    86 ******************** 我是分割线 ********************
    87 {'_c': 42.22222222222222, '_f': 108, '_k': None}
    88 42.22222222222222 315.3722222222222 108
    89 {'_c': 42.22222222222222, '_f': 108, '_k': 315.3722222222222}
    参考案例

    5>. 模拟购物车购物 

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 
     7 class Color:
     8     RED = 0
     9     BLUE = 1
    10     GREEN = 2
    11     GOLDEN = 3
    12     BLACK = 4
    13     OTHER = 1000
    14 
    15 
    16 class Item:
    17     def __init__(self,**kwargs):
    18         self.__spec = kwargs
    19 
    20     def __repr__(self):
    21         return str(sorted(self.__spec.items()))
    22 
    23 
    24 class Cart:
    25     def __init__(self):
    26         self.items = []
    27 
    28     def additem(self,item:Item):
    29         self.items.append(item)
    30 
    31     def getallitems(self):
    32         return self.items
    33 
    34 mycart = Cart()
    35 myphone = Item(mark="Huawei",color=Color.GOLDEN,memory="4G")
    36 mycart.additem(myphone)
    37 
    38 mycar = Item(mark="Red Flag",color = Color.BLACK,year=2019)
    39 mycart.additem(mycar)
    40 
    41 print(mycart.getallitems())
    42 
    43 
    44 
    45 #以上代码执行结果如下:
    46 [[('color', 3), ('mark', 'Huawei'), ('memory', '4G')], [('color', 4), ('mark', 'Red Flag'), ('year', 2019)]]
    参考案例
  • 相关阅读:
    大型网站前端使用图片格式的正确姿势
    移动端开发技术文档
    超详细的Web前端开发规范文档
    try 、catch 、finally 、throw 测试js错误
    ajax大并发问题
    jQuery之Ajax--全局Ajax事件处理器
    如何处理ajax中嵌套一个ajax
    关于for循环里面异步操作的问题
    XMLHttpRequest: 网络错误 0x2f78,…00002f78
    【转载】OGRE中用到的设计模式
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11155050.html
Copyright © 2011-2022 走看看