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>.类对象及类属性
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class MyClass:
""" A Example Class."""
CLASSNAME = "bigdata & devops" #类属性,也可以称之为类的变量。需要注意它和实例变量的区别。实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法。一般来说,类变量可使用全大写来命名。即表示常量。 """
1>.通常,每次实例化后获得的实例,是不同的实例,即使是使用同样的参数实例化,也得到不一样的对象。和Java语法类似,Python类实例化过程中,
首先会调用new方法进行实例化(可以理解为创建出对象),然后会自动调用 __init__ 方法(可以理解为对已经创建出的对象进行初厂设置)。这个方法第
一个形式参数必须留给self,其它形式参数随意。
2>.该方法可以不定义,如果定义会在实例化后隐式调用。它的作用就是对实例进行初始化。
3>.该方法不能有返回值,也就是只能return None。
"""
def __init__(self,name:str,age:int):
"""
我们知道self表示的是当前实例对象,我们这里为当前实例绑定2个实例变量(即name和age),它并不属于类属性,它属于实例对象。
"""
self.name = name
self.age = age """
类的普通方法(method),也是类属性。本质上就是普通的函数对象function,它一般要求至少有一个参数。第一个形式参数可以是self(self只是个
惯用标识符,可以换名字),这个参数位置就留给了self。它指代当前实例本身。
类实例化后,得到一个实例对象,实例对象会绑定到方法上,即会把方法的调用者实例作为第一参数self的实参传入。
"""
def showme(self): #类
return self.name print(MyClass) #不会调用"__init__"方法,因为咱们没有对MyClass类进行实例化操作。
print(MyClass.showme)
print(MyClass.__doc__) #注意,这里的"__doc__"也是类的特殊属性。
print(MyClass.__name__) #对象名
print(MyClass.__class__) #对象的类型
print(MyClass.__dict__) #对象的属性字典
print(MyClass.__qualname__) #类的限定名 print("{0} {1} {0}".format("*"*10,"注意:Python中每一种对象都拥有不同的属性。函数是对象,类是对象,类的实例也是对象。")) s1 = MyClass("Jason",18) #实例化过程中会自动调用"__init__"方法进行初始化操作,然后类实例化后一定会获得一个类的实例,它就是实例对象s1。
print(s1.showme()) #s1是Myclass类实例化后得到的一个实例对象,实例对象会绑定到方法上,因此我们这里就不需要为 showme(self)方法传参,直接调用即可,如果有2个或以上参数那调用时除了第一个参数不需要传递外,其他参数依旧是要传入的哟。
print(s1.__dict__) #以上代码输出结果如下:
<class '__main__.MyClass'>
<function MyClass.showme at 0x10215fae8>
A Example Class.
MyClass
<class 'type'>
{'__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>}
MyClass
********** 注意:Python中每一种对象都拥有不同的属性。函数是对象,类是对象,类的实例也是对象。 **********
Jason
{'name': 'Jason', 'age': 18}
3>.实例属性的查找顺序
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
总结
是类的,也是这个类所有实例的,其实例都可以访问到;
是实例的,就是这个实例自己的,通过类访问不到。
类变量是属于类的变量,这个类的所有实例可以共享这个变量。
对象(实例或类)可以动态的给自己增加一个属性(赋值即定义一个新属性)。
实例.__dict__[变量名] 和 实例.变量名 都可以访问到实例自己的属性(注意这两种访问是有本质区别的)。 实例的同名变量会隐藏掉类变量,或者说是覆盖了这个类变量。但是注意类变量还在那里,并没有真正被覆盖。 实例属性的查找顺序
指的是实例使用 .点号 来访问属性,会先找自己的 __dict__ ,如果没有,然后通过属性 __class__ 找到自己的类,再去类的 __dict__ 中找
注意:如果实例使用 __dict__[变量名] 访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key 查找,不是属性查找。
""" class Person:
age = 3 #一般来说,类变量可使用全大写来命名。我们这里为了实验效果,故意将类变量和实例变量命令部分重复以达到测试目的。
height = 170 def __init__(self,name,age=18):
self.name = name
self.age = age tom = Person("Tom")
jason = Person("Jason",20) Person.age = 30
print(1,Person.age,tom.age,jason.age)
print(2,Person.height,tom.height,jason.height) jason.height = 175 #动态为jason对象设置"height"属性
print(3,Person.height,tom.height,jason.height) tom.height += 10 #其实等价于tom.height = tom.height + 10,由于tom的"__dict__"没有"height"属性,因此它会去Person类的"__dict__中找"
print(4,Person.height,tom.height,jason.height) Person.height += 15
print(5,Person.height,tom.height,jason.height) Person.weight = 70
print(6,Person.weight,tom.weight,jason.weight) print(7,Person.__dict__)
print(8,tom.__dict__)
print(9,jason.__dict__) print(10,tom.__dict__["height"])
# print(11,tom.__dict__["weight"]) #会抛出"KeyError: 'weight'"异常! #以上代码输出结果如下:
1 30 18 20
2 170 170 170
3 170 170 175
4 170 180 175
5 185 180 175
6 70 70 70
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}
8 {'name': 'Tom', 'age': 18, 'height': 180}
9 {'name': 'Jason', 'age': 20, 'height': 175}
10 180
四.装饰一个类(即类装饰器)
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
需求,为一个类通过装饰,增加一些类属性。例如能否给一个类增加一个NAME类属性并提供属性值.
"""
def add_name(name):
def wrapper(cls):
cls.NAME = name
return cls
return wrapper @add_name("Jason")
class Person:
AGE = 18 print(Person.NAME) #之所以能够装饰,本质上是为类对象动态的添加了一个属性,而Person这个标识符指向这个类对象。 #以上代码输出结果如下:
Jason
五.类方法和静态方法
1>.普通函数(最好禁止在类中定义无参函数)
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Person:
def __init__(self,name,age):
self.name = name
self.age = age def normal_method(): #注意:在Python中虽然语法是对的,但是,没有人这么用,也就是说禁止这么写
print("normal") Person.normal_method() #可以放在类中定义,因为这个方法只是被Person这个名词空间管理的一个普通的方法,normal_method是Person 的一个属性而已。类是可以调用的,但该类的实例不能调用该方法。 p1 = Person("Jason",18) # p1.normal_method() #由于normal_method在定义的时候没有指定形参self,所以不能完成实例对象的绑定,因此p1实例不能调用。只要一调用就会为normal_method传递一个self参数,而原方法是一个无参函数。只要一调用该方法就报错!!!
2>.类方法
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Person:
def __init__(self,name,age):
self.name = name
self.age = age """
类方法:(类似于C++、Java中的静态方法)
1>.在类定义中,使用@classmethod装饰器修饰的方法
2>.必须至少有一个参数,且第一个参数留给了cls,cls指代调用者即类对象自身
3>.cls这个标识符可以是任意合法名称,但是为了易读,请不要修改
4>.通过cls可以直接操作类的属性 注意:无法通过cls操作类的实例。为什么?
"""
@classmethod
def class_method(cls):
print("class = {0.__name__} ({0})".format(cls))
print("class = {0.__dict__} ({0})".format(cls)) Person.class_method() #使用类对象直接调用类方法,访问的是类的属性 jason = Person("Jason",18)
jason.class_method() #使用类的实例化对象调用类方法,访问的还是类的属性 #以上代码输出结果如下:
class = Person (<class '__main__.Person'>)
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'>)
class = Person (<class '__main__.Person'>)
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>.静态方法
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Person:
def __init__(self,name,age):
self.name = name
self.age = age @classmethod
def class_method(cls):
print("class = {0.__name__} ({0})".format(cls))
cls.HEIGHT = 170
"""
静态方法
1>.在类定义中,使用@staticmethod装饰器修饰的方法
2>.调用时,不会隐式的传入参数
静态方法,只是表明这个方法属于这个名词空间。函数归在一起,方便组织管理。
"""
@staticmethod
def static_methd(cls):
print(Person.HEIGHT) Person.class_method() jason = Person("Jason",18) Person.static_methd(jason) #使用类对象调用静态方法时,需要手动传入参数。 print(Person.__dict__)
print(jason.__dict__) #以上代码执行结果如下:
class = Person (<class '__main__.Person'>)
170
{'__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}
{'name': 'Jason', 'age': 18}
4>.方法的调用
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie """
类可以定义这么多种方法,究竟如何调用它们?
总结:
类除了普通方法都可以调用,普通方法需要类对象的实例作为第一参数。
实例可以调用所有类中定义的方法(包括类方法、静态方法),普通方法传入实例自身,静态方法和类方法需要找到实例的类(因为实例"__dict__"中没有
静态方法和类方法属性,他得去实例的类中"__dict__"的去查找想要的属性)。
""" class Person:
"""
我们称没有用"classmethod"或"staticmethod"装饰器修饰的方法为普通方法。
类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一参数必须是类的实例。
实例也几乎可以调用所有的方法, 普通的函数的调用一般不可能出现,因为原则上不允许这么定义。
"""
def method(self):
print("{}'s method".format(self)) @classmethod
def class_method(cls): # cls是什么
print('class = {0.__name__} ({0})'.format(cls))
cls.HEIGHT = 170 @staticmethod
def static_methd():
print(Person.HEIGHT) print("{0} {1} {0}".format("*"*10,"类访问"))
#print(1, Person.method()) #会抛出异常,因为咱们类调用普通方法需要手动传参数,而实例调用由于做了实例绑定,因此实例调用则不需要传参数哟。
print(2, Person.class_method())
print(3, Person.static_methd()) print("{0} {1} {0}".format("*"*10,"jason实例访问"))
jason = Person()
print(4, jason.method())
print(5, jason.class_method())
print(6, jason.static_methd()) print("{0} {1} {0}".format("*"*10,"对比类对象和类实例对象"))
print(7,"Person:{}\t Person实例:{}\t".format(Person.method,jason.method)) #我们可以通过打印Person和Person实例的普通方法地址就可以看出点端倪,实例对象被普通方法做了实例绑定。
print(8,Person.__dict__)
print(9,jason.__dict__) #以上代码输出结果如下:
********** 类访问 **********
class = Person (<class '__main__.Person'>)
2 None
170
3 None
********** jason实例访问 **********
<__main__.Person object at 0x102961208>'s method
4 None
class = Person (<class '__main__.Person'>)
5 None
170
6 None
********** 对比类对象和类实例对象 **********
7 Person:<function Person.method at 0x10295fae8> Person实例:<bound method Person.method of <__main__.Person object at 0x102961208>>
8 {'__module__': '__main__', '__doc__': '\n 我们称没有用"classmethod"或"staticmethod"装饰器修饰的方法为普通方法。\n 类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一参数必须是类的实例。\n 实例也几乎可以调用所有的方法, 普通的函数的调用一般不可能出现,因为原则上不允许这么定义。\n ', '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}
9 {}
六.小试牛刀
1>.机整数生成类
可以先设定一批生成数字的个数,可设定指定生成的数值的范围。运行时还可以调整每批生成数字的个数
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self.count = count def generate(self):
return [random.randint(self.start,self.stop) for i in range(self.count)] print(RandomGen().generate())
print(RandomGen(200,1000,5).generate()) #以上代码执行结果如下:
[25, 32, 14, 7, 15, 94, 41, 68, 85, 58]
[715, 428, 920, 954, 217]
参考一:普通类实现
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen: @classmethod
def generate(cls,start=1,stop=100,count=10):
return [random.randint(start,stop) for i in range(count)] print(RandomGen().generate())
print(RandomGen().generate(200,1000,5)) #以上代码执行结果如下:
[19, 21, 89, 86, 65, 58, 94, 29, 76, 71]
[461, 392, 229, 732, 575]
参考二:作为工具类来实现,提供类方法
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self.count = count
self._gen = self._generate() def _generate(self):
while True:
yield random.randint(self.start,self.stop) def generate(self):
return [next(self._gen) for i in range(self.count)] print(RandomGen().generate())
print(RandomGen(200,1000,5).generate()) #以上代码执行结果如下:
[96, 15, 55, 87, 43, 21, 100, 55, 96, 81]
[501, 208, 657, 806, 499]
参考三:生成器实现
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self.count = count
self._gen = self._generate() def _generate(self):
while True:
yield random.randint(self.start,self.stop) def generate(self):
yield from (next(self._gen) for i in range(self.count)) print(list(RandomGen().generate()))
print(list(RandomGen(200,400,5).generate())) #以上代码执行结果如下:
[51, 25, 94, 2, 16, 75, 9, 20, 2, 21]
[285, 211, 249, 271, 309]
参考四:生成器变形一
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self.count = count
self._gen = self._generate() def _generate(self):
while True:
yield random.randint(self.start,self.stop) def generate(self,count=0): #可以后期在产生数据时控制个数。
count = self.count if count <= 0 else count
return [next(self._gen) for i in range(count)] print(RandomGen().generate())
print(RandomGen(600,900).generate(5)) #以上代码执行结果如下:
[36, 84, 45, 26, 32, 91, 42, 75, 49, 36]
[647, 885, 642, 857, 852]
参考五:生成器变形二
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self._count = count #保护变量
self._gen = self._generate() def _generate(self):
while True: #一次yield一批
yield [random.randint(self.start,self.stop) for _ in range(self._count)] def generate(self,count=0): #可以后期在产生数据时控制个数。
if count > 0:
self._count = count
return next(self._gen) print(RandomGen().generate())
print(RandomGen(1000,2000).generate(5)) #以上代码执行结果如下:
[51, 20, 52, 31, 64, 47, 43, 75, 47, 98]
[1606, 1570, 1063, 1842, 1427]
参考六:生成器变形三
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self._count = count #保护变量
self._gen = self._generate() def _generate(self):
while True: #一次yield一批
yield [random.randint(self.start,self.stop) for _ in range(self._count)] def generate(self):
return next(self._gen) @property
def count(self):
return self._count @count.setter
def count(self,count):
self._count = count r = RandomGen(100,200)
print(r.count)
print(r.generate()) r.count = 5
print(r.count)
print(r.generate()) #以上代码执行结果如下:
10
[130, 188, 174, 127, 180, 144, 189, 105, 146, 119]
5
[157, 145, 168, 131, 105]
参考七:使用property属性装饰器实现
2>.打印坐标
使用上题中的类,随机生成20个数字,两两配对形成二维坐标系的坐标,把这些坐标组织起来,并打印输出
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import random class RandomGen:
def __init__(self,start=1,stop=100,count=10):
self.start = start
self.stop = stop
self._count = count #保护变量
self._gen = self._generate() def _generate(self):
while True: #一次yield一批
yield [random.randint(self.start,self.stop) for _ in range(self._count)] def generate(self):
return next(self._gen) @property
def count(self):
return self._count @count.setter
def count(self,count):
self._count = count class Point:
def __init__(self,x,y):
self.x = x
self.y = y r = RandomGen()
points = [Point(x,y) for x,y in zip(r.generate(),r.generate())] for p in points:
print("{:2}:{:2}".format(p.x,p.y)) #以上代码执行结果如下:
44: 1
66:59
40: 3
92:73
90:73
22:67
98:47
82:10
17:69
36:39
参考案例
3>.车辆信息
记录车的品牌mark、颜色color、价格price、速度speed等特征,并实现车辆管理,能增加车辆、显示全部车辆的信息功能
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Car:
def __init__(self,mark,speed,color,price):
self.mark = mark
self.speed = speed
self.color = color
self.price = price class CarInfo:
def __init__(self):
self.__info = [] def addcar(self,car:Car):
self.__info.append(car) def getall(self):
return self.__info ci = CarInfo()
car = Car('audi',400,'red',100)
ci.addcar(car) ci.getall() #返回所有数据,此时再实现格式打印
参考案例
4>.实现温度的处理
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Temperature:
def __init__(self,t,unit='c'):
self._c = None
self._f = None
self._k = None #都要先转换到摄氏度,以后访问再计算其它单位的温度值
if unit == 'f':
self._f = t
self._c = self.f2c(t)
elif unit == 'k':
self._k = t
self._c = self.k2c(t)
else:
self._c = t @property
def c(self):
return self._c @property
def f(self): #华氏温度
if self._f is None:
self._f = self.c2f(self._c)
return self._f @property
def k(self): #开氏温度
if self._k is None:
self._k = self.c2k(self._c)
return self._k @classmethod
def c2f(cls,c):
return 9 * c / 5 + 32 @classmethod
def f2c(cls,f):
return (f - 32 ) * 5 / 9 @classmethod
def c2k(cls,c):
return c + 273.15 @classmethod
def k2c(cls,k):
return k - 273.15 @classmethod
def f2k(cls,f):
return cls.c2k(cls.f2c(f)) @classmethod
def k2f(cls,k):
return cls.c2f(cls.k2c(k)) print(Temperature.c2f(30))
print(Temperature.f2c(108))
print(Temperature.c2k(30))
print(Temperature.k2c(520.13))
print(Temperature.f2k(108))
print(Temperature.k2f(520.13)) print("{0} 我是分割线 {0}".format("*" * 20)) t = Temperature(108,'f')
print(t.__dict__)
print(t.c,t.k,t.f)
print(t.__dict__) #以上代码执行结果如下:
86.0
42.22222222222222
303.15
246.98000000000002
315.3722222222222
476.564
******************** 我是分割线 ********************
{'_c': 42.22222222222222, '_f': 108, '_k': None}
42.22222222222222 315.3722222222222 108
{'_c': 42.22222222222222, '_f': 108, '_k': 315.3722222222222}
参考案例
5>. 模拟购物车购物
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie class Color:
RED = 0
BLUE = 1
GREEN = 2
GOLDEN = 3
BLACK = 4
OTHER = 1000 class Item:
def __init__(self,**kwargs):
self.__spec = kwargs def __repr__(self):
return str(sorted(self.__spec.items())) class Cart:
def __init__(self):
self.items = [] def additem(self,item:Item):
self.items.append(item) def getallitems(self):
return self.items mycart = Cart()
myphone = Item(mark="Huawei",color=Color.GOLDEN,memory="4G")
mycart.additem(myphone) mycar = Item(mark="Red Flag",color = Color.BLACK,year=2019)
mycart.additem(mycar) print(mycart.getallitems()) #以上代码执行结果如下:
[[('color', 3), ('mark', 'Huawei'), ('memory', '4G')], [('color', 4), ('mark', 'Red Flag'), ('year', 2019)]]
参考案例
Python入门篇-面向对象概述的更多相关文章
- Python入门篇-装饰器
Python入门篇-装饰器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.装饰器概述 装饰器(无参) 它是一个函数 函数作为它的形参 返回值也是一个函数 可以使用@functi ...
- Python入门篇-functools
Python入门篇-functools 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.reduce方法 reduce方法,顾名思义就是减少 reduce(function,se ...
- Python入门篇-高阶函数
Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数 1>.First Class Object 函数在Python中是一等公民 函数也 ...
- Python入门篇-生成器函数
Python入门篇-生成器函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.生成器概述 1>.生成器generator 生成器指的是生成器对象,可以由生成器表达式得到, ...
- Python入门篇-匿名函数
Python入门篇-匿名函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.匿名函数概述 1>.什么是匿名函数 匿名,即没有名字 匿名函数,即没有名字的函数 2>. ...
- Python入门篇-递归函数Recursion
Python入门篇-递归函数(recursion) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.递归概述 (1)函数直接或者间接调用自身就是递归: (2)递归需要有边界,递归 ...
- Python入门篇-数据结构树(tree)篇
Python入门篇-数据结构树(tree)篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.树概述 1>.树的概念 非线性结构,每个元素可以有多个前躯和后继 树是n(n& ...
- Python入门篇-返回值和作用域
Python入门篇-返回值和作用域 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.返回值 1>.返回值概述 Python函数使用return语句返回“返回值” 所有函数都 ...
- Python入门篇-函数、参数及参数解构
Python入门篇-函数.参数及参数解构 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数概述 1>.函数的作用即分类 函数 数学定义:y=f(x) ,y是x的函数,x ...
随机推荐
- Html JavaScript网页制作与开发完全学习手册
Html JavaScript网页制作与开发完全学习手册 篇 HTML技术章 HTML入门 1.1 什么是HTML 1.1.1 HTML的特点 1.1.2 HTML的历史 1.2 HTML文件的基本结 ...
- [原]使用kubeadm部署kubernetes(一)
####################### 以下为声明 ##################### 在公众号 木子李的菜田 输入关键词: k8s 有系列安装文档 此文档是之前做笔记在 ...
- 在 Hibernate 中inverse的属性
hibernate配置文件中有这么一个属性inverse,它是用来指定关联的控制方的.inverse属性默认是false,若为false,则关联由自己控制,若为true,则关联由对方控制.见例子: 一 ...
- java:字符串的split方法,使用多个分隔符,分割一个字符串
java语言中,多个分隔符,分割一个字符串: String[] tmpAuthors=tempAuthorStr.split(";|,|:|,"); 可以在线测试:java代码 在 ...
- Git 克隆
工作中大家分工协作,共同开发维护一个项目,git仓库放在公共的服务器上,如github.Gitee等. 在这种情况使用git,需要先克隆仓库到本地. 克隆非常简单,使用命令git clone 将远程仓 ...
- 【记录】【java】JDK8新特性Stream方式遍历集合
由于是以流方式,所以怎么操作也不改变原来的集合 1.普通遍历forEach List<String> list = new ArrayList(); list.add("a&qu ...
- 【手写代码】计算1-n中总共有多少二进制1
#include<bits/stdc++.h> #include<vector> using namespace std; //时间复杂度:O(N) int f(int x) ...
- [转帖]LINUX PID 1 和 SYSTEMD
LINUX PID 1 和 SYSTEMD 2017年07月16日 陈皓 评论 46 条评论 57,176 人阅读 https://coolshell.cn/articles/17998.html ...
- Java基础知识点总结(二)
“https://www.runoob.com/java” 1.Java运算符优先级 2.内置数据类型的包装类 抽象类Number是所有包装类(Integer.Long.Byte.Double.Flo ...
- Django框架之第四篇(视图层)--HttpRequest对象、HttpResponse对象、JsonResponse、CBV和FBV、文件上传
视图层 一.视图函数 一个视图函数,简称视图,是一个简单的python函数,它接收web请求并且会返回web响应.响应可以是一张网页的html,一个重定向,或者是一张图片...任何东西都可以.无论是什 ...