Python学习—面向对象学习下
class People(object): # 构造方法:__init__(),在实例化对象时自动执行的方法 def __init__(self, name, age): self.name = name self.age = age print("创建对象成功.......") # 析构函数:__del__(), 当你删除对象时,自动调用的方法 # 删除对象:del 对象名 def __del__(self): print("删除对象成功.......")
1.构造函数:init()
用于初始化类的内容部状态,也就是当该类被实例化的时候就会执行该函数。那么我们就可以把要先初始化的属性放到这个函数里面。
init()方法是可选的,如果不提供,Python 会给出默认的init方法。一般数据的获取需要定义的get和set方法
当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数也会被调用一次,这样可以用来释放内存空间。
del()也是可选的,如果不提供,则Python 会在后台提供默认析构函数如果要显式的调用析构函数,可以使用del关键字,方式:del 对象名
repr和str这两个方法都是用于显示的,str是面向用户的,而repr面向程序员。
想使用print(Object)显示对象,那就需要重构str。想直接输入类对象Object来打印,那就需要重构repr,当然它也可以使用print(Object)显示对象。区别在于:当你打印一个类的时候,那么print首先调用的就是类里面的定义的str方法,而不是repr方法,在没有str方法时才会去调用repr方法。
#定义类>>> class Test(): def __init__(self): self.ppx = "hello,python."#实例化类,然后想直接获取类的一些信息>>> t = Test()>>> t<__main__.Test object at 0x0000000002F3EF28>>>> print(t)<__main__.Test object at 0x0000000002F3EF28>
在没有str或者repr方法时,上面打印类对象显示的是对象的内存地址
下面我们重构下该类的repr以及str,看看它们俩的区别
>>> class TestRepr(Test): def __repr__(self): return "Show:%s"%self.ppx>>> t1 = TestRepr()>>> t1Show:hello,python.>>> print(t1)Show:hello,python.
可以看到,重构repr方法后,不管直接输出对象还是通过print打印的信息都按我们repr方法中定义的格式进行显示
>>> class TestStr(Test): def __str__(self): return "Show: %s"%self.ppx>>> t2 = TestStr()>>> t2<__main__.TestStr object at 0x00000000031C33C8>>>> print(t2)Show: hello,python.
直接输出对象ts时并没有按我们str方法中定义的格式进行输出,而用print(Object)输出的信息才会这样显示。
3.formate方法1.通过位置来填充字符串print("hello %s" % ('world'))print("hello {0}".format((1, 2, 3, 4)))print("hello {0} {1} {0} {1}".format((1, 2, 3, 4), "python"))print("hello {0:.3f}".format(1.8989))运行输出:hello worldhello (1, 2, 3, 4)hello (1, 2, 3, 4) python (1, 2, 3, 4) python
2.通过key来填充
print("max:{max} min:{min}".format(min=10, max=100))运行输出:max:100 min:10
3.通过下标/index填充
point = (3,4)print("x:{0[0]}, y:{0[1]}".format(point))输出:x:3, y:4
4.通过字典的key
d = {'max':100.7849758475976, 'min':10.4756895769857985}print("max:{max:.2f} min:{min:.3f}".format(**d))运行输出:max:100.78 min:10.476
5. oop对象进行操作
class Book(object): def __init__(self, name, author, state, bookIndex): self.name = name self.author = author # 0:借出 1:未借出 self.state = state self.bookIndex = bookIndex # 打印对象时自动调用;str(对象) def __str__(self): return "书名:{0.name} 状态:{0.state}".format(self) # return "书名:{d.name} 状态:{d.state}".format(d=self)b = Book("java", 'aa', 1, 'Index')print(b)运行输出:书名:java 状态:1
6. 对象中的format魔术方法
# 定义一个存储年月日输出格式的字典formats = { 'ymd':"{d.year}-{d.month}-{d.day}", 'mdy':"{d.month}/{d.day}/{d.year}",}class Date(object): def __init__(self, year, month, day): self.year = year self.month = month self.day = day # format方法: format(对象名)时自动调用 def __format__(self, format_spec=None): if not format_spec: format_spec = 'ymd' fmt = formats[format_spec] # "{d.year}-{d.month}-{d.day}".format(d=d) return fmt.format(d=self)d = Date(2019, 8, 25)print(format(d)) #不传入参数print(format(d, 'mdy')) #传入参数运行输出:2019-8-258/25/2019
4.关于@property
习惯了高级语言的严谨,总想对属性加以访问控制,相对安全些,比如直接在init中定义公用属性,从封装性来说,它是不好的写法。属性访问控制机制,其一是@propery关键字。用此关键字,其获取、设置函数,须与属性名一致。
br/>属性访问控制机制,其一是@propery关键字。用此关键字,其获取、设置函数,须与属性名一致。
from requests.compat import basestringclass Animal(object): def __init__(self, name, age): self._name = name self._age = age self._color = 'Black' # 将普通方法变为属性方法 @property def name(self): return self._name # 当更改name的值时,自动调用下面这个方法。这样就可以更改属性的值了 @name.setter def name(self, value): if isinstance(value, basestring): self._name = value else: self._name = 'No name' #获取值 @name.getter def get(self): return self.name @property def age(self): return self._age @age.setter def age(self, value): if value > 0 and value < 100: self._age = value else: self._age = 0 @property def color(self): return self._color @color.setter def color(self, value): self._color = value;a = Animal('black dog', 3)a.name = 'white dog'a.age = 55a.color = 'red'print('Name:', a.name)print('Age:', a.age)print('Color:', a.color)print(a.get)运行结果:Name: white dogAge: 55Color: redwhite dog
5.类里面的切片与索引
魔术方法getitem、setitem与delitem
1.对列表的操作
class Student(object): def __init__(self, name, scores): self.name = name self.scores = scores # 支持索引; s[index] def __getitem__(self, index): # print("获取索引对应的value值") return self.scores[index] # s[索引] = 修改的值 def __setitem__(self, index, value): self.scores[index] = value # del s[索引] def __delitem__(self, index): del self.scores[index] def hello(self): return "hello"s = Student('westos', [101, 100, 100])# *********************************索引**************************print(s[0])print(s[1])print(s[2])#更改值s[0] = 200print(s[0])print(s.scores)#删除值del s[0]print(s.scores)# *********************************切片**************************print(s[1:3])s[1:3] = [0,0]print(s[:])del s[:-1]print(s[:])print(s[0])运行结果:101100100200[200, 100, 100][100, 100][100][100, 0, 0][0]0
2.对字典的操作
class Student(object): def __init__(self, name, scores): self.name = name self.scores = scores # 支持索引; s[key] def __getitem__(self, key): # print("获取索引对应的value值") return self.__dict__[key] # s[key] = 修改的值 def __setitem__(self, key, value): self.__dict__[key] = value # del s[key] def __delitem__(self, key): del self.__dict__[key] def hello(self): return "hello"s = Student('westos', [101, 100, 100])#**************************key获取value值***********************print(s.__dict__)print(s['name'])print(s['scores'])s['name'] = 'westo1'print(s['name'])del s['name'] #删除一个键值对# print(s['name']) #如果查值,会报错:key不存在运行结果:{'name': 'westos', 'scores': [101, 100, 100]}westos[101, 100, 100]westo1
6.call()方法
当一个类实现call方法时,这个类的实例就会变成可调用对象。即函数。
1.
class ClassA: def __call__(self, *args, **kwargs): print('call ClassA instance.......')# ClassA实现了__call__方法a = ClassA()#这个时候,ClassA的实例a,就变成可调用对象#调用a(),输出call ClassA instance,说明是调用了__call__函数a()# 其实a()等同于a.__call__(),它本质上就是后者的缩写a.__call__()运行结果:call ClassA instance.......call ClassA instance.......
2.
class Dddd(object): def __init__(self, origin): self.origin = origin print("origin :"+str(origin)) def __call__(self, x): print("x :"+str(x))p = Dddd(100)p(2000)运行结果:origin :100x :2000
7.实现一个单例模式
class Student(object): def __init__(self, name, scores, power): self.name = name self.scores = scores self.power = power # 实例化对象之前先执行下面这个new魔术方法 def __new__(cls, *args, **kwargs): # 判断是否obj对象是否已经被创建, 如果没有被创建, 则创建, if not hasattr(cls, 'obj'): cls.obj = object.__new__(cls) # 如果已经创建成功,则返回创建好的对象 return cls.objs1 = Student('westos1', [101,100,100], 100)s2 = Student('westos1', [101,100,100], 100)print(s1)print(s2)运行结果:<__main__.Student object at 0x7fedfa2ebef0><__main__.Student object at 0x7fedfa2ebef0>
可以看见,对象s1,s2他们指向的地址相同,即他们时同一个对象。而不是两个相同值的对象。
8.类中的安全上下文with语句enter()与exit()
class MyOpen(object): def __init__(self, filename, mode='r'): self._name = filename self._mode = mode # 当with语句开始运行的时候,执行此方法; def __enter__(self): self.f = open(self._name, self._mode) return self.f # 当with语句执行结束之后运行; def __exit__(self, exc_type, exc_val, exc_tb): self.f.close()with MyOpen('/etc/passwd') as f: print(f.closed) print(f.read(5))print(f.closed)运行如果:Falseroot:True
9.反射
反射:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)。即 让对象告诉我们相关信息(对象拥有的属性和方法, 对象所属的类等....)
hasattr(object,name)
判断object中有没有一个name字符串对应的方法或属性,注意私有属性或者方法不能判断出来
getattr(object, name, default=None)
获取object中有没有对应的方法和属性,私有属性或者方法不能判断出来不能获取到。default是设置当获取不到时的返回值,默认为None
setattr(x, y, v)
修改或添加对象的属性
delattr(x, y)
删除类或对象的属性
class Student(object): """ 这是student类的帮助文档 """ def __init__(self, name, age): self.name = name self.__age = age def get_score(self): return "score" def get_grade(self): return 'grade's1 = Student("fentiao", 10)print(type(s1))print(isinstance(s1, Student))print(isinstance('hello', Student))# 跟据对象可以获取的内容print(s1.__class__) #类信息print(s1.__dict__) #生成字典print(s1.__doc__) #获取帮助文档# hasattr, getattr, setattr, delattr# hasattr: 判断对象是否包含对应的属性或者方法名;print(hasattr(s1, 'name'))print(hasattr(s1, '__age')) # 私有属性, 私有方法, 是不能判断的;print(hasattr(s1, 'score'))print(hasattr(s1, 'get_score'))print(hasattr(s1, 'set_score'))# getattrprint(getattr(s1, 'name'))print(getattr(s1, '__age', 'no attr'))print(getattr(s1, 'get_score', 'no method')) # 获取方法名, 如果要执行方法, 直接调用即可print(getattr(s1, 'set_score', 'no method')) # 获取方法名, 如果要执行方法, 直接调用即可# setattr:# 修改某个属性的值setattr(s1, 'name', 'westos')print(getattr(s1, 'name'))# 添加某个属性及对应的值;setattr(s1, 'score', 100)print(getattr(s1, 'score'))# 修改方法def get_score1(): return "这是修改的方法内容"setattr(s1, 'get_score', get_score1)print(getattr(s1, 'get_score')())def set_score(): return "这是添加的方法"# 添加方法setattr(s1, 'set_score', set_score)print(getattr(s1, 'set_score')())# delattrdelattr(s1, 'name')print(hasattr(s1, 'name'))print(hasattr(s1, 'set_score'))delattr(s1, 'set_score')print(hasattr(s1, 'set_score'))运行结果:<class '__main__.Student'>TrueFalse<class '__main__.Student'>{'name': 'fentiao', '_Student__age': 10} 这是student类的帮助文档TrueFalseFalseTrueFalsefentiaono attr<bound method Student.get_score of <__main__.Student object at 0x7efc6b8a3ac8>>no methodwestos100这是修改的方法内容这是添加的方法FalseTrueFalse
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。