继承:解决代码重用问题
多态:多态性,可以在不考虑对象类型的情况下而直接使用对象
封装:明确的区分内外,控制外部对隐藏属性的操作行为,隔离复杂度
类的属性:数据属性和函数属性,数据属性是所有对象共有的,函数属性是绑定对象使用的
对象的属性:对象是类的实例化
面向过程:复杂的问题流程化,简单化应用场景:不再需要扩展了,监测脚本,自动部署脚本,软件解压安装
面向对象:特征与技能的结合体 一切皆对象应用场景:用户需求经常变化,互联网应用,游戏,企业内部应用
类和对象的属性:以字典的形式保存的
绑定到对象的方法:就应该由对象来调用,def tell_info(self):…obj.tell_info()
绑定到类的方法:就应该由类来调用,@classmethod def from_conf(cls):… class.from_conf()
非绑定方法:不与类或对象绑定,谁都可以调用,@staticmethod def create_id():… obj.create_if()/class.create_id()
class A(object):
pass
a = A()
a["key"] = "val"
a = a["key"]
del a["key"]
# class A(object):
# def __setitem__(self, key, value):
# self.__dict__[key] = value#
# def __getitem__(self, item):#
# return self.__dict__[item]
# return self.__dict__.get(item)#
# def __delitem__(self, key):
# del self.__dict__[key]## a = A()
# a["key"] = "val"
# print(a.__dict__)#
# a = a["key"]#
# print(a)
# del a["key"]
# print(a.__dict__)
经典类:py2 没有继承object的类,以及它的子类都称之为经典类 --> 深度优先
新式类:py3 继承object的类,以及它的子类都称之为新式类 -->广度优先
class People(object):
__name = "luffy"
__age = 18
p1 = People()
print(p1.__name, p1.__age)
# print(p1.__name, p1.__age)
# 报错:AttributeError: 'People' object has no attribute '__name'
print(p1.__dict__) #{}
print(People.__dict__)
# {'__module__': '__main__', '_People__name': 'luffy',
# '_People__age': 18, '__dict__': ,
# '__weakref__': , '__doc__': None}
print(p1._People__name,p1._People__age) # luffy 18
class People(object):
def __init__(self):
print("__init__")
def __new__(cls, *args, **kwargs):
print("__new__")
return object.__new__(cls, *args, **kwargs)
People()
# 结果:__new__
# __init__
class A(object):
def foo(self, x):
print("executing foo(%s, %s)" % (self,x))
@classmethod
def class_foo(cls, x):
print("executing class_foo(%s, %s)" % (cls,x))
@staticmethod
def static_foo(x):
print("executing static_foo(%s)" % (x))
a = A()
静态方法:非绑定方法,类和对象都可以调用 类方法:绑定给类的方法啊,类调用
class A(object):
def __init__(self,name):
self.name=name
def foo(self, x):
print("executing foo(%s, %s)" % (self,x))
@classmethod
def class_foo(cls, x):
print("executing class_foo(%s, %s)" % (cls,x))
@staticmethod
def static_foo(x):
print("executing static_foo(%s)" % (x))
# a = A('alice')
# a.foo('alice')
# A.class_foo('alice')
# a.static_foo('alice')
# A.static_foo('alice')
'''executing foo(<__main__.A object at 0x000002A5FED12AC8>, alice)
executing class_foo(, alice)
executing static_foo(alice)
executing static_foo(alice)'''
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print(" %s is eating" %self.name)
d = Dog("ChenRonghua")
d.eat()
错误原因:@property可以将函数属性转化为数据属性
报错内容:
Traceback (most recent call last):
File "D:/py.py", line 27, in <module>
d.eat()
TypeError: 'NoneType' object is not callable
改正:
class Dog(object):
def __init__(self,name):
self.name = name
@property
def eat(self):
print(" %s is eating" %self.name)
d = Dog("ChenRonghua")
d.eat
因为有了property,用户就可以直接输入得到结果,对于使用者来说,感知不到其属性,这就是使用property的方便之处,此方法必须有一个返回值。return 或者print都可以。
为什么要用property?
一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
# 1 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址
# 1 2 1 更改Child1,Child1的x指向了新的内存地址
# 3 2 3 更改Parent,Parent的x指向了新的内存地址
class Animal:
def __init__(self, name):
self.name = name
class People(Animal):
def talk(self):
print('%s is talking' % self.name)
class Dog(Animal):
def talk(self):
print('%s is talking' % self.name)
def func(animal):
animal.talk()
# p=People('alice')
# d=Dog('wang')
# func(p)
# func(d)
'''alice is talking
wang is talking'''
class Student:
__count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Student.__count += 1
@property
def talk(self):
print('%s is talking' % self.name)
@staticmethod
def tell_count():
print('总共实例化了 %s 人' % Student.__count)
# s1 = Student('alice', 18)
# s2 = Student('alex', 20)
# s3 = Student('egon', 28)
# Student.tell_count()
# s1.tell_count()
# s1.talk
# s2.talk
结果:
1
{
'name': 'james', 'sex': 'male', 'age': 32}
2
{
'name': 'enbede', 'sex': 'male', 'age': 23}
2
{
'__module__': '__main__', '_count': 2, '__init__': <function Student.__init__ at 0x00000190B1B959D8>, 'learn': <property object at 0x00000190B19047C8>, 'tell_count': <staticmethod object at 0x00000190B1B9CAC8>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
总共实例化了:2
james is learning
class B:
def handle(self):
print('from B handle')
class A(B):
def handle(self):
super().handle()
# print('from A handle')
# a=A()
# a.handle()
要求:
1.英雄需要有昵称、攻击力、生命值等属性;
2.实例化出两个英雄对象;
3.英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡。
class Hero:
def __init__(self,nickname,life_value,aggresivity):
self.nickname = nickname
self.life_value = life_value
self.aggresivity = aggresivity
def attack(self,enemy):
enemy.life_value -= self.aggresivity
class Garen(Hero):
pass class Riven(Hero): p
assg1=Garen('草丛论',100,20)
r1 = Riven('放逐之刃',80,50)
print(r1.life_value)
g1.attack(r1)
print(r1.life_value)