首頁 > 後端開發 > Python教學 > python物件導向進階篇

python物件導向進階篇

巴扎黑
發布: 2017-08-18 13:34:01
原創
1069 人瀏覽過

下面小編就為大家帶來一篇python進階_淺談物件導向。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧

學了物件導向三大特性繼承,多型,封裝。今天我們來看看物件導向的一些進階內容,反射和一些類別的內建函數。

一、isinstance與issubclass


#
class Foo:
 pass

class Son(Foo):
 pass

s = Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
print(isinstance(s,Son))
print(isinstance(s,Foo))
#type更精准
print(type(s) is Son)
print(type(s) is Foo)

#判断一个类是不是另一类的子类,传两个参数(子类,父类)
print(issubclass(Son,Foo))
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))
登入後複製

class Foo:
 def __init__(self):
  self.name = 'egon'
  self.age = 73

 def func(self):
  print(123)

egg = Foo()
#常用:
#hasattr
#getattr
# print(hasattr(egg,'name'))
print(getattr(egg,'name'))
if hasattr(egg,'func'): #返回bool
 Foo_func = getattr(egg,'func') #如果存在这个方法或者属性,就返回属性值或者方法的内存地址
         #如果不存在,报错,因此要配合hasattr使用
 Foo_func()
#不常用:
#setattr
# setattr(egg,'sex','属性值')
# print(egg.sex)
# def show_name(self):
#  print(self.name + ' sb')
# setattr(egg,'sh_name',show_name)
# egg.sh_name(egg)
# show_name(egg)
# egg.sh_name()

#delattr
# delattr(egg,'name')
# print(egg.name)


# print(egg.name)
# egg.func()
# print(egg.__dict__)


#反射
#可以用字符串的方式去访问对象的属性、调用对象的方法
反射举例1
登入後複製

二、反射

反射的概念是由Smith在1982年首次提出的,主要是指程式可以存取、偵測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快就引發了計算機科學領域關於應用反射的研究。它首先被程式語言的設計領域所採用,並在Lisp和物件導向方面取得了成績。

python物件導向中的反射:
透過字串的形式操作物件相關的屬性。 python中的一切事物都是物件(都可以使用反射)


四個可以實現反射的函數:

hasattr,getattr,setattr,delattr

下列方法適用於類別與物件(一切皆對象,類別本身也是物件)



class Foo:
 f = 123 #类变量
 @classmethod
 def class_method_demo(cls):
  print('class_method_demo')
 @staticmethod
 def static_method_demo():
  print('static_method_demo')
# if hasattr(Foo,'f'):
#  print(getattr(Foo,'f'))
print(hasattr(Foo,'class_method_demo'))
method = getattr(Foo,'class_method_demo')
method()
print(hasattr(Foo,'static_method_demo'))
method2 = getattr(Foo,'static_method_demo')
method2()
#类也是对象
登入後複製


import my_module
# print(hasattr(my_module,'test'))
# # func_test = getattr(my_module,'test')
# # func_test()
# getattr(my_module,'test')()
#import其他模块应用反射

from my_module import test


def demo1():
 print('demo1')

import sys
print(__name__) #'__main__'
print(sys.modules)
#&#39;__main__&#39;: <module &#39;__main__&#39; from &#39;D:/Python代码文件存放目录/S6/day26/6反射3.py&#39;>
module_obj =sys.modules[__name__] #sys.modules[&#39;__main__&#39;]
# module_obj : <module &#39;__main__&#39; from &#39;D:/Python代码文件存放目录/S6/day26/6反射3.py&#39;>
print(module_obj)
print(hasattr(module_obj,&#39;demo1&#39;))
getattr(module_obj,&#39;demo1&#39;)()
#在本模块中应用反射
反射举例3
登入後複製

反射範例2

#对象
#类
#模块 : 本模块和导入的模块

def register():
 print(&#39;register&#39;)

def login():
 pass

def show_shoppinglst():
 pass
#
print(&#39;注册,登录&#39;)
ret = input(&#39;欢迎,请输入您要做的操作: &#39;)
import sys
print(sys.modules)
# my_module = sys.modules[__name__]
# if hasattr(my_module,ret):
#  getattr(my_module,ret)()
if ret == &#39;注册&#39;:
 register()
elif ret == &#39;登录&#39;:
 login()
elif ret == &#39;shopping&#39;:
 show_shoppinglst()
反射举例4
登入後複製

def test():
 print(&#39;test&#39;)
登入後複製

#
class Foo:
 def __init__(self,name):
  self.name = name
 def __str__(self):
  return &#39;%s obj info in str&#39;%self.name
 def __repr__(self):
  return &#39;obj info in repr&#39;

f = Foo(&#39;egon&#39;)
# print(f)
print(&#39;%s&#39;%f)
print(&#39;%r&#39;%f)
print(repr(f)) # f.__repr__()
print(str(f))
#当打印一个对象的时候,如果实现了str,打印中的返回值
#当str没有被实现的时候,就会调用repr方法
#但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
#不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
#但反之不行
#用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr
登入後複製


三、類別的內建函數

#1、__str__和__repr__

#

class Foo:
 def __del__(self):
  print(&#39;执行我啦&#39;)

f = Foo()
print(123)
print(123)
print(123)
#析构方法,当对象在内存中被释放时,自动触发执行。
#注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
登入後複製

2、__del__





##

class Foo:
 def __init__(self):
  self.name = &#39;egon&#39;
  self.age = 73
  
 def __getitem__(self, item):
  return self.__dict__[item]

 def __setitem__(self, key, value):
  # print(key,value)
  self.__dict__[key] = value

 def __delitem__(self, key):
  del self.__dict__[key]
f = Foo()
print(f[&#39;name&#39;])
print(f[&#39;age&#39;])
f[&#39;name&#39;] = &#39;alex&#39;
# del f[&#39;name&#39;]
print(f.name)
f1 = Foo()
print(f == f1)
登入後複製
3、item系列


__getitem__\__setitem__\__delitem__


##
# class A:
#  def __init__(self): #有一个方法在帮你创造self
#   print(&#39;in init function&#39;)
#   self.x = 1
#
#  def __new__(cls, *args, **kwargs):
#   print(&#39;in new function&#39;)
#   return object.__new__(A, *args, **kwargs)
# a = A()
# b = A()
# c = A()
# d = A()
# print(a,b,c,d)

#单例模式
class Singleton:
 def __new__(cls, *args, **kw):
  if not hasattr(cls, &#39;_instance&#39;):
   cls._instance = object.__new__(cls, *args, **kw)
  return cls._instance

one = Singleton()
two = Singleton()
three = Singleton()
go = Singleton()
print(one,two)

one.name = &#39;alex&#39;
print(two.name)
登入後複製


4、__new__


###
class Foo:
 def __init__(self):
  pass
 def __call__(self, *args, **kwargs):
  print(&#39;__call__&#39;)

obj = Foo() # 执行 __init__
obj() # 执行 __call__
Foo()() # 执行 __init__和执行 __call__
#构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
登入後複製
######5、__call__################################################################
class Foo:
 def __len__(self):
  return len(self.__dict__)
 def __hash__(self):
  print(&#39;my hash func&#39;)
  return hash(self.name)
f = Foo()
print(len(f))
f.name = &#39;egon&#39;
print(len(f))
print(hash(f))
登入後複製
######6、__len__,__hash__################
class A:
 def __init__(self):
  self.a = 1
  self.b = 2

 def __eq__(self,obj):
  if self.a == obj.a and self.b == obj.b:
   return True
a = A()
b = A()
print(a == b)

#__eq__控制着==的结果
登入後複製
######7、__eq__############## ##
class FranchDeck:
 ranks = [str(n) for n in range(2,11)] + list(&#39;JQKA&#39;)
 suits = [&#39;红心&#39;,&#39;方板&#39;,&#39;梅花&#39;,&#39;黑桃&#39;]

 def __init__(self):
  self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
          for suit in FranchDeck.suits]

 def __len__(self):
  return len(self._cards)

 def __getitem__(self, item):
  return self._cards[item]

deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))

纸牌游戏
登入後複製
###8、內建函數實例############
class FranchDeck:
 ranks = [str(n) for n in range(2,11)] + list(&#39;JQKA&#39;)
 suits = [&#39;红心&#39;,&#39;方板&#39;,&#39;梅花&#39;,&#39;黑桃&#39;]

 def __init__(self):
  self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
          for suit in FranchDeck.suits]

 def __len__(self):
  return len(self._cards)

 def __getitem__(self, item):
  return self._cards[item]

 def __setitem__(self, key, value):
  self._cards[key] = value

deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))

from random import shuffle
shuffle(deck)
print(deck[:5])

纸牌游戏2
登入後複製
##########
class Person:
 def __init__(self,name,age,sex):
  self.name = name
  self.age = age
  self.sex = sex

 def __hash__(self):
  return hash(self.name+self.sex)

 def __eq__(self, other):
  if self.name == other.name and other.sex == other.sex:return True


p_lst = []
for i in range(84):
 p_lst.append(Person(&#39;egon&#39;,i,&#39;male&#39;))

print(p_lst)
print(set(p_lst))

#只要姓名和年龄相同就默认为一人去重
登入後複製
#########rrreee

以上是python物件導向進階篇的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板