类与对象
对象 = 属性 + 方法
封装:信息隐蔽技术
继承:子类自动共享父类之间数据和方法的机制
多态:不同对象对同一方法响应不同的行动
class test1:
start_num=10
def getStartNum(self):
return self.start_num
def add(self,num):
return num+self.start_num
t1 = test1()
num = t1.getStartNum()
print(num)
#10
num = t1.add(6)
print(num)
#16
class test2(list):
pass#空语句
l1= test2([11,12]);
l1.append(1)
l1.sort(reverse=True)#倒序
print(l1)
#[12, 11, 1]
class empty:
def make(self):
raise BaseException("just empty")
class book(empty):
def make(self):
print('page')
class man(empty):
def make(self):
print('c & h2o')
class test3(empty):
def test(self):
print('i am test')
book().make()
man().make()
test3().test()
test3().make()
'''
page
c & h2o
i am test
Traceback (most recent call last):
File "H:\code\python\test5.py", line 36, in <module>
test3().make()
File "H:\code\python\test5.py", line 23, in make
raise BaseException("just empty")
BaseException: just empty
'''
第一个参数为self,且方法定义时比须设为第一个参数。
Self相当于 C++ 的 this
指针,指代自身。
在调用方法时,无需明确提供与参数 self
相对应的参数。
魔法方法
构造方法:__init__(self[, param1, param2...])
定义私有变量只需要在变量名或函数名前加上“__”两个下划线,php之前也是,之后都不用了,看着乱。
class test4:
__attr1 = 10
attr2=11
def __init__(self,num):
self.attr2+=num
self.__attr1-=num
def public(self):
print('i am public')
def __private(self):
print("con't say me")
def getAttr1(self):
return self.__attr1
t2 = test4(2)
t2.public()
print(t2.getAttr1())
print(t2.attr2)
t2.__private()
'''
i am public
8
13
Traceback (most recent call last):
File "H:\code\python\test5.py", line 66, in <module>
t2.__private()
AttributeError: 'test4' object has no attribute '__private'
'''
继承
BaseClassName
(基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用。
class DerivedClassName(BaseClassName):
statement-1
.
.
.
statement-N
class DerivedClassName(modname.BaseClassName):
statement-1
.
.
.
statement-N
class DerivedClassName(Base1, Base2, Base3):
statement-1
.
.
.
statement-N
支持类似于Java重写一样的操作,子类成员方法覆盖父类成员方法。
多重继承,需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。
class book:
price = 10
title = 'test' #类属性
__version_code = 'No1110'
def __init__(self,price,title,versionCode):
self.price = price #实例属性
self.title = title
self.__version_code = versionCode
self.info()
def info(self):
print("title:%s price:%d code:%s" % (self.title,self.price,self.__version_code))
class test1(book):
def __init__(self,price,title,versionCode):
book.__init__(self,price,title,versionCode)
self.price = self.price*4 #实例属性
book.price = self.price #类属性
book.info(self)
def info(self):
print(self.price,book.price)
print("title:%s price:%d" % (self.title,self.price))
class test2(book):
def info(self):
print(self.price,book.price)
print("title:%s price:%d" % (self.title,self.price))
super().info()
t1 = test1(2,'code story','No1112')
t1.info()
'''
2 10
title:code story price:2
title:code story price:8 code:No1112
8 8
title:code story price:8
'''
t2 = book(4,'code story2','No1114')
t2.info()
'''
title:code story2 price:4 code:No1114
title:code story2 price:4 code:No1114
'''
t3 = test2(8,'code story8','No1118')
t3.info()
'''
8 10
title:code story8 price:8
8 10
title:code story8 price:8
'''
经测试,调用子类的方法,相同函数父类执行子类的方法,并且子类成员方法改变不了父类已经定义的成员变量。后者原因大概是子类构造覆盖父类构造,但self对象指向不同,所以没改变父类的值。
也就是self只能改变被调用对象的成员变量,果然和this差不多……php用this的话会得改变后的值,java是获取父类之前定义好的值,java获取父类对象是super,python里为super()。
python有点像模式设计的注入,所以可以多个继承,也就是类名后的参数列表中加多个父类。
类属性:类里面方法外面定义的变量称为类属性。类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。
实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另外一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他的对象不能直接使用,因为self
是谁调用,它的值就属于该对象。
属性与方法名相同,属性会覆盖方法。
绑定
Python 严格要求方法需要有实例才能被调用,这种限制其实就是 Python 所谓的绑定概念。
Python 对象的数据属性通常存储在名为.__ dict__
的字典中,可以直接访问__dict__
,或利用 Python 的内置函数vars()
获取.__ dict__
。
class Test:
def test1(self,x,y):
self.x=x
self.y=y
def showInfo(self):
print(self.x,self.y)
t1 = Test()
print(t1.__dict__)
#{}
print(vars(t1))
#{}
t1.test1(10,11)
print(t1.__dict__)
#{'x': 10, 'y': 11}
print(vars(t1))
#{'x': 10, 'y': 11}
内置函数
issubclass(class, classinfo)
方法用于判断参数 class 是否是类型参数 classinfo 的子类。- 一个类被认为是其自身的子类。
classinfo
可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True
。isinstance(object, classinfo)
方法用于判断一个对象是否是一个已知的类型,类似type()
。type()
不会认为子类是一种父类类型,不考虑继承关系。isinstance()
会认为子类是一种父类类型,考虑继承关系。- 如果第一个参数不是对象,则永远返回
False
。 - 如果第二个参数不是类或者由类对象组成的元组,会抛出一个
TypeError
异常。 hasattr(object, name)
用于判断对象是否包含对应的属性。getattr(object, name[, default])
用于返回一个对象属性值。setattr(object, name, value)
对应函数getattr()
,用于设置属性值,该属性不一定是存在的。delattr(object, name)
用于删除属性。class property([fget[, fset[, fdel[, doc]]]])
用于在新式类中返回属性值。fget
-- 获取属性值的函数fset
-- 设置属性值的函数fdel
-- 删除属性值函数doc
-- 属性描述信息
class Test:
def test1(self,x,y):
self.x=x
self.y=y
def showInfo(self):
print(self.x,self.y)
t1 = Test()
print(t1.__dict__)
#{}
print(vars(t1))
#{}
t1.test1(10,11)
print(t1.__dict__)
#{'x': 10, 'y': 11}
print(vars(t1))
#{'x': 10, 'y': 11}
class Test1(Test):
pass
print(issubclass(Test1,Test))
#True
print(issubclass(Test,Test1))
#False
print(issubclass(Test,Test))
#True
print(issubclass(Test,object))
#True
t2 = 10
print(isinstance(t2,int))
#True
print(isinstance(t2,str))
#False
#print(isinstance(t2,[str,int,list]))
'''
Traceback (most recent call last):
File "test5.py", line 31, in <module>
print(isinstance(t2,[str,int,list]))
TypeError: isinstance() arg 2 must be a type or tuple of types
'''
print(isinstance(t2,(str,int,list)))
#True
print(isinstance(Test1(),Test))
#True
print(isinstance(Test(),Test))
#True
t2 = Test1()
t2.test1(1,4)
print(hasattr(t2,'x'))
#True
print(hasattr(t2,'t'))
#False
print(getattr(t2,'y'))
#4
t3 = getattr(t2,'test1')
t3(1,5)
print(getattr(t2,'x'),getattr(t2,'y'))
#1 5
setattr(t2,'z',2)
print(t2.x,t2.y,t2.z)
#1 5 2
print(vars(t2))
#{'x': 1, 'y': 5, 'z': 2}
delattr(t2,'z')
print(vars(t2))
#{'x': 1, 'y': 5}
class Test2(object):
def __init__(self):
self.__x = 123
def getx(self):
return self.__x
def setx(self,value):
self.__x=value
def delx(self):
del self.__x
x = property(getx,setx,delx,'is x property')
t4 = Test2()
t4.x = '213'
print(t4.x)
#213
del t4.x
#print(t4.x)
'''
Traceback (most recent call last):
File "test5.py", line 80, in <module>
print(t4.x)
File "test5.py", line 70, in getx
return self.__x
AttributeError: 'Test2' object has no attribute '_Test2__x'
'''
#https://www.liaoxuefeng.com/wiki/897692888725344/923030547069856
class Student(object):
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
@property
def age(self):
return 2014 - self._birth
student = Student();
#student.age = 10
'''
Traceback (most recent call last):
File "test5.py", line 103, in <module>
student.age = 10
AttributeError: can't set attribute
'''
student.birth =10
print(vars(student))
#{'_birth': 10}