1、面向對象編程python
# 1.什麼是面向對象 面向過程與面向對象 面向過程編程:解決問題從過程出發,解決問題步驟化 面向對象編程:解決問題從對象出發,解決問題找對象 對象與類 類:對象的類型 => 數字 具備相同特徵與行爲集合的抽象 對象:類的具體表現 => 數字10 類的實例化,就是具備特徵與行爲實際存在的個體(每個對象都是惟一的) # 2.爲何要面向對象編程 面向過程:開發成本高,解決問題侷限性小 面向對象:開發成本低,解決問題侷限於對象 問題:'abc' => {'a', 'b', 'c'} 面向過程: 本身寫 面向對象:str => list => set #(引用模塊) 開發:優選面向對象(找解決問題的對象), 再考慮找多個對象(面向對象與面向過程的結合), 最後本身去封裝一個能夠解決問題的對象(對外是面向對象的體現,內部解決問題的核心是面向過程)
# 例如:
s = 'abc' # => ['a', 'b', 'c'] # 解決方案 # re.findall() list初始化方法 # for循環append # 面向過程:解決問題步驟化 res = [] for c in s: res.append(c) print(res) # 面向對象:解決問題找對象 # -- 對象如何解決問題:對象.解決問題的方法() # 找re對象 import re res = re.findall(r'[a-z]', s) print(res) # 找list對象 res = list(s) print(res) # 模塊 md.py def print_num(a): print(a) from md import print_num as pn pn(100) pn(200)
2、類的聲明語法linux
class 類名: # 在該縮進下(在類下)定義多個函數,類名就能夠總體管理全部的函數,經過點語法來調用具體的函數 def fn1(): print('fn1 run') def fn2(): print('fn2 run') def fn3(): print('fn3 run') # 類名的命名規範:採用大駝峯
3、點語法與名稱空間算法
def fn(): pass class Fn(): def a_fn(): pass pass import md print(fn, fn.__dict__) # <function fn at 0x0000000001CF2EA0> {} print(Fn, Fn.__dict__) # <class '__main__.Fn'> {'__module__': '__main__', 'a_fn': <function Fn.a_fn at 0x0000000002947048>, '__dict__': <attribute '__dict__' of 'Fn' objects>, '__weakref__': <attribute '__weakref__' of 'Fn' objects>, '__doc__': None} print(md, md.__dict__) #<module 'md' from 'F:\\安裝包\\JetBrains\\JetBrains\\Projects\\09\\代碼\\part2\\md.py'> {'__name__': 'md', '__doc__': None, '__package__': '', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001EA6E10>, '__spec__': ModuleSpec(name='md', loader=<_frozen_importlib_external.SourceFileLoader object at 0x0000000001EA6E10>, origin='F:\\安裝包\\JetBrains\\JetBrains\\Projects\\09\\代碼\\part2\\md.py'), '__file__': 'F:\\安裝包\\JetBrains\\JetBrains\\Projects\\09\\代碼\\part2\\md.py', '__cached__': 'F:\\安裝包\\JetBrains\\JetBrains\\Projects\\09\\代碼\\part2\\__pycache__\\md.cpython-36.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <built-in function input>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'WindowsError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'BufferError': <class 'BufferError'>, 'MemoryError': <class 'MemoryError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-Z plus Return to exit, 'exit': Use exit() or Ctrl-Z plus Return to exit, 'copyright': Copyright (c) 2001-2017 Python Software Foundation. # All Rights Reserved. ... # 訪問名字的底層 print(Fn.__dict__['__module__']) # __main__ # 訪問名字的語法優化 print(Fn.__module__) # __main__ # 總結:對象.名字 本質 對象.__dict__['名字'] # 賦值 fn.name = '我寫的函數' print(fn.__dict__) # {'name': '我寫的函數'} print(fn.__dict__['name']) # 我寫的函數 print(fn.name) # 我寫的函數 # 瞭解:對象的名稱空間,與對象內部的名稱空間不是同一個 print('========================================') def func(): a = 10 b = 20 print(locals()) # {'b': 20, 'a': 10} func() print(func.__dict__) # {} # 記住: # 對象.名字 = 值 是爲該對象添加一個名稱空間的名字, # 也只能經過 對象.名字 來使用 func.name = 'func function' print(func.name) # func function
# 能夠產生名稱空間的語法 def fn(): # 具備名稱空間:fn.__dict__ pass class Fn(): # 具備名稱空間:Fn.__dict__ pass import md # 具備名稱空間:md.__dict__ # 名稱空間如何爲一個名字設置值,或訪問一個名字對應的值 fn.__dict__[名字] = 值 # 設置值 print(fn.__dict__[名字]) # 取值 # 重點:名稱空間取值賦值的語法優化:點語法 fn.名字 = 值 # 設置值 print(fn.名字) # 取值
4、類與對象的聲明編程
class People: name = '人' p1 = People() p2 = People() # 結論1:類與每個對象的名稱空間都是獨立的 print(p1.__dict__) # {} print(p2.__dict__) # {} print(People.__dict__) # {'name': '人', ...系統的} # 結論2:類與每個對象均可以使用類中的名字 print(People.name) # 人 print(p1.name) # 人 print(p2.name) # 人 # 結論3:對象訪問名字,優先訪問本身的,本身沒有再訪問類的 p1.name = '張三' p2.user = '李四' print(People.name) # 人 print(p1.name) # 張三 print(p2.user) # 李四 print(p2.name) # 人 # 重點: # 對象操做名字,操做的是對象的,類操做名字操做的是類的,之間相互不干預 # 類只能訪問類的名字 # 對象訪問名字,優先訪問自身的,自身沒有再訪問類的
5、類的初始化方法安全
# 能夠快速爲類實例化出的每個對象,產生對象名稱空間中的多個名字 class NewTeacher: def __init__(self, name, sex, age): # print(id(self)) # self就是實例化產生的對象(nt1) # print('init 被調用了') self.name = name self.sex = sex self.age = age pass # 類()就是在調用類的__init__方法 nt1 = NewTeacher('王大錘', '男', 58) # print(id(nt1)) print(nt1.name, nt1.sex, nt1.age) nt2 = NewTeacher('王小錘', '男', 48) print(nt2.name, nt2.sex, nt2.age)
演化:app
class Teacher: name = '教授' def set_obj(obj, name, sex, age): obj.name = name obj.sex = sex obj.age = age t1 = Teacher() # t1.name = 'C老師' # t1.sex = "女" # t1.age = 36 set_obj(t1, 'C老師', "女", 36) print(t1.name, t1.sex, t1.age) t2 = Teacher() # 類()應該就是函數的調用,函數調用能夠傳參,能優化屬性的賦值 # t2.name = 'W老師' # t2.sex = "女" # t2.age = 28 set_obj(t2, 'W老師', "女", 28) print(t2.name, t2.sex, t2.age) # t3 = Teacher() # set_obj(t3, '王大錘', '男', 58) # 能不能再優化 => t3 = Teacher('王大錘', '男', 58) # print(t3.name, t3.sex, t3.age)
6、類的方法分類ide
# 對象方法:直接定義的方法,建議由對象調用,類中內部須要使用對象的數據時的方法要定義爲對象方法 # 1.對象方法對象調用,默認傳入對象給第一個形參 class 類名: def fn(self, *args, **kwargs): pass # 類方法:被classmethod修飾的方法,建議由類調用,類中內部須要使用類的數據時的方法要定義爲類方法 # 2.類方法由類調用,默認傳入類給第一個形參 class 類名: @classmethod def fn(cls, *args, **kwargs): pass # 靜態方法:被staticmethod修飾的方法,建議由類調用,類中內部不須要類相關數據時的方法要定義爲靜態方法 # 3.靜態方法建議由類調用,默認不傳入調用者 @staticmethod def fn(*args, **kwargs): pass
案例1:函數
class Student: name = '學生' def __init__(self, name, id_num): self.name = name self.id_num = id_num # 對象(成員)方法 def study(self): # 在類中產生的全部方法,都是屬於類的,可是對象能夠調用 # print('self>>', id(self)) print("%s在學習" % self.name) # 類方法: 第一個參數就是用來接收調用者,類方法的調用者必定是類,因此第一個參數命名約定爲cls @classmethod def fn(cls): print(id(cls)) # 靜態方法 @staticmethod def func(): print('func run') stu1 = Student('Bob', 1) print(stu1.__dict__) # {'name': 'Bob', 'id_num': 1} print(stu1.name) # Bob # stu1.__dict__.clear() # 清空stu1 # print(stu1.__dict__) # {} # print(stu1.name) # 學生 print("====================") stu2 = Student('Tom', 2) stu1.study() # Bob在學習 print(id(stu1)) # 32140984 stu2.study() # Tom在學習 print(id(stu2)) # print("====================") # 結論1:對象調用類中的方法,默認隱式將對象自身傳入,在方法中,第一個參數用self來接受傳入的對象 # Student.fn(Student) => Student.fn() # print(id(Student)) Student.fn() # 41758904 print(id(Student)) # 41758904 # 結論2:類中用@classmethod裝飾的方法,是類方法,用類來調用,默認會將類傳入給方法的第一個參數 print("====================") Student.func() # func run stu1.func() # func run # 結論3:類中用@staticmethod裝飾的方法,是靜態方法,能夠被類和對象調用,默認不會將類或對象傳入
案例二:類的不一樣方法應用工具
# 案例 class Book: name = '書' def __init__(self, name, price): self.name = name self.price = price # 書的詳情信息 => 必定須要知道哪本書 # @classmethod # 類調用cls就是類,對象調用處理成 對象.__class__ def detail(self): # print(cls.name) print("%s的價格爲:%s元" % (self.name, self.price)) book1 = Book('西遊記', 38.8) book2 = Book('三國', 88.8) book1.detail() book2.detail() # print(book1.__class__) # 靜態方法:方法的內部不須要對象及類的參與,因此定義爲靜態方法,可是方法必須由調用者,建議用類就能夠了 class NumTool: # 工具類 => 模塊 def max_two(self, n1, n2): max_num = n1 if n1 > n2 else n2 print('大數是%s' % max_num) @staticmethod def new_max_two(n1, n2): max_num = n1 if n1 > n2 else n2 print('大數是%s' % max_num) n1 = NumTool() n2 = NumTool() n1.max_two(10, 20) n2.max_two(10, 20) NumTool.new_max_two(10, 20) n1.new_max_two(10, 20) # 類方法:方法的內部須要類的參與,因此定義爲類方法,第一個參數默認傳類 class NewNumTool: PI = 3.14 @classmethod def new_max_two(cls, n1, n2): max_num = n1 if n1 > n2 else n2 return max_num @classmethod def new_max_three(cls, n1, n2, n3): # max_num = "想去複用new_max_two" max_num = cls.new_max_two(n1, n2) max_num = cls.new_max_two(max_num, n3) return max_num @classmethod def is_PI(cls, num): if num == cls.PI: return True return False res = NewNumTool.new_max_three(1, 5, 3) print('大數是%s' % res) print(NewNumTool.is_PI(3.149))
7、封裝學習
# 什麼是封裝:將類的一下屬性和方法對外隱藏,對內可見 # 爲何要封裝:爲屬性和方法的操做添加權限,具體權限都是經過自定義邏輯來處理 # 封裝的手段:在類屬性方法,對象屬性方法,靜態方法名字前添加 __ # 只要是經過 __名字 這種命名規範,就是對外隱藏 # 本質:__名字 封裝隱藏變量的本質是 將名字修飾成 _類名__名字 # 對外解決封裝的方式 # 1.若是真的不想讓外界訪問,就不對外提供訪問數據的方法 # 2.若是想讓外界訪問,能夠對外提供訪問數據的方法,方法具備邏輯,使用能夠添加操做權限 class Test: def __init__(self, name): # __name只是對外隱藏,對內可見 self.__name = name def get_name(self): return self.__name def set_name(self, name): if 'sb' not in name: # 對數據的修改可能會產生數據的安全性問題,能夠添加限制條件 self.__name = name
# 重點:封裝的對外訪問語法的優化 class User: def __init__(self, name): self.__name = name @property # 將方法假裝成屬性 def name(self): return self.__name @name.setter # 能爲有假裝get方法的(方法)屬性,再假裝set方法 def name(self, value): self.__name = value @name.deleter def name(self): del self.__name # 總結: # 1.對象沒了,對象的屬性也就沒了,因此不須要屬性 @名字.deleter # 2.對外提供get方法是基礎,@property,若是沒有,外界不可讀不可寫 # 3.若是有@property,則能夠 @名字.setter,有set,爲可讀可寫,無set爲只讀 @property # 假裝的屬性方法,不須要必定有 __開頭 的名字與之對應 def pwd(self): return '123456' u1 = User('Owen') print(u1.name) # 若是一個方法假裝成屬性,對象.方法名 就會自動調用該方法 u1.name = 'Zero' print(u1.name) # del u1.name # print(u1.name) print(u1.pwd)
#@property 將方法假裝成屬性,從而能夠像__init__裏的屬性同樣調用u1.name
8、類的繼承
什麼是繼承
繼承是一種新建類的方式,繼承的類稱之爲子類或派生類
被繼承的類稱之爲父類或基類或超類
子類繼承父類,也就意味着子類繼承了父類全部的屬性和方法
能夠直接調用
爲何要有繼承
減小代碼冗餘
如何使用
class Parent1: pass class Parent2: pass class Son1(Parent1): pass # python中支持多繼承 class Son2(Parent1,Parent2): pass # 如何查看類的父類 print(Son1.__bases__) # (<class '__main__.Parent1'>,) print(Son2.__bases__) # (<class '__main__.Parent1'>, <class '__main__.Parent2'>) # 自定義的沒有顯示繼承任何類的父類到底有沒有偷偷繼承某個類呢? print(Parent1.__bases__) # (<class 'object'>,) print(Parent2.__bases__) # (<class 'object'>,)
# python2:類若是沒有顯示繼承任何類的狀況下,不繼承任何類 # python3:類若是沒有顯示繼承任何類的狀況下,默認都繼承object類 經典類與新式類 經典類: 不繼承object或者其子類的類 叫經典類 新式類: 繼承object或者其子類的類 叫新式類 # ps:經典類與新式類只在python2有區分 #python3中只有新式類
派生:
# 派生:在繼承了父類的屬性和方法的基礎之上 本身定義了其餘的屬性和方法 # 若是派生出的方法與父類的同名了 那麼至關於覆蓋了父類的方法 # 類:一系列對象類似的特徵與技能的結合體 # 類與類之間類似的特徵與技能的結合體 >>> 父類 # 類:一系列對象類似的特徵與技能的結合體 # 類與類之間類似的特徵與技能的結合體 >>> 父類 import pickle class OldboyPeople: school = 'oldboy' def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def save(self): with open(self.name,'wb') as f: pickle.dump(self,f) class OldboyStudent(OldboyPeople): def choose_course(self): print('%s is choosing course'%self.name) class OldboyTeacher(OldboyPeople): def __init__(self,name,age,gender,level): OldboyPeople.__init__(self,name,age,gender) self.level = level def score(self): print('%s is score'%self.name) stu = OldboyStudent('simon',18,'male') print(stu.name) # simon stu.save() # 建立文件存數據 tea = OldboyTeacher('xc',18,'male',10) print(tea.name) # simon tea.save()
子類方法中調用父類的方法:
# 方法一:指名道姓 # OldboyPeople.__init__(self,name,age,gender) 跟繼承一點關係都沒有 # 方法二:和繼承有關係 # 單繼承狀況下的屬性查找 class B: def f1(self): print('from B f1') def f2(self): print('from B f2') self.f1() class A(B): def f1(self): print('from A f1') obj = A() obj.f2() """ from B f2 from A f1 """ # 上面的例子能夠看出:類是查找順序是先查找本身,再查找父類
# 多繼承
# 不管是python2仍是python3繼承都遵循深度優先(菱型繼承除外) # 深度優先:依次先從左邊分支查找完後向右查找 # # 多繼承 class D: # def test(self): # print('D') pass class E: def test(self): print('E') class F: def test(self): print('F') class A(D): # def test(self): # print('A') pass class B(E): # def test(self): # print('B') pass class C(F): def test(self): print('C') class G(A,B,C): # def test(self): # print('G') pass obj = G() obj.test() # E
# 調用方式 import pickle class OldboyPeople: school = 'oldboy' def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def save(self): with open(self.name,'wb') as f: pickle.dump(self,f) class OldboyTeacher(OldboyPeople): def __init__(self,name,age,gender,level): # OldboyPeople.__init__(self,name,age,gender) # super(OldboyTeacher,self).__init__(name,age,gender) super().__init__(name,age,gender) # 調用 self.level = level tea = OldboyTeacher('ymc',18,'male',10) print(tea.name) # ymc tea.save()
MRO列表,C3算法
# mro列表 C3算法 class D: pass class E: pass class F: pass class A(D): pass class B(E): pass class C(F): pass class G(A,B,C): pass
print(G.mro()) """ G A D B E C F [<class '__main__.G'>, <class '__main__.A'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class 'object'>] """
# super是嚴格按照mro列表的順序調用父類的方法的!!!
class A: def f1(self): print('from a f1') def f2(self): print('from a f2') super().f1() class B: def f1(self): print('from b f1') def f2(self): print('from b f2') class C(A,B): def f1(self): print('from c f1') print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] obj = C() obj.f2() """ from a f2 from b f1 """
9、多態與多態性
# 什麼是多態 一種事物的不一樣形態(動物:人,狗,貓),代碼層面上來講其實就是繼承 # 爲何要有多態 多態僅僅是一個概念 # 多態性:在不須要考慮對象具體類型的狀況下 調用對象的方法 # 如何使用
class Animal: def talk(self): pass class People(Animal): def talk(self): print('hello') class Dog(Animal): def talk(self): print('wangwang') class Cat(Animal): def talk(self): print('miaomiao') people = People() dog = Dog() cat = Cat() people.talk() dog.talk() cat.talk()
# 例如:len獲取長度
10、反射
# 經過字符串來操做對象的屬性或方法
# 經過字符串來操做對象的屬性或方法 class User: school = 'oldgirl' def __init__(self,name,age): self.name = name self.age = age def func(self): print('func') # hasattr判斷對象是否有某個屬性或方法 print(User.school) # oldgirl print('school' in User.__dict__) # True print('xxx' in User.__dict__) # False print(hasattr(User,'school')) # True print(hasattr(User,'xxx')) # False print(hasattr(User,'func')) # True print('func' in User.__dict__) # True d = {'name':"jason"} print(d.get('password','hahahahahaha')) # hahahahahaha # getattr 取類中的屬性或方法 print(getattr(User,'school')) # oldgirl print(getattr(User,'func')) # <function User.func at 0x00000000021F7048> print(User.__dict__['school']) # oldgirl print(User.__dict__['func']) # <function User.func at 0x00000000027D7048> # print(getattr(User,'xxx')) # 獲取沒有的報錯 if hasattr(User,'xxx'): getattr(User,'xxx') # setattr obj = User('simon',18) setattr(obj,'gender','male') # obj.gender = 'male' print(obj.__dict__) # delattr delattr(User,'school') print(User.__dict__)
11、內置方法
class User: def __init__(self,name,password): self.name = name self.password = password def __str__(self): # return '%s:%s'%(self.name,self.password) return '我被打印了,自動觸發' def __getattr__(self, item): print(item) def __setattr__(self, key, value): print(key,value) # __str__對象被執行了打印操做 自動觸發 obj = User('simon',123) print(User) print(obj) """ name simon password 123 <class '__main__.User'> 我被打印了,自動觸發 """ # __getattr__ 當對象獲取一個不存在的屬性時候纔會觸發 obj = User('simon',18) print(obj.name) """ name simon password 18 name None """ # __setattr__: obj.name = 'xxx' 固定句式 obj = User('simon',18) obj.sex = 'sexy' """ name simon password 18 sex sexy """ class Demo(dict): def __getattr__(self, item): return self.get(item) d = Demo(name='simon',password=123) print(d.name) # simon print(d.password) # 123
做業一:
1.自定義一個 Fruit 類:該類有一個 類屬性: identify:值爲"水果",有兩個對象屬性: name,price:值由實例化對象時賦值,
一個類方法: get_identify:打印類屬性identify的值,
一個對象方法:get_total_price(num):打印『%s個%s值%s錢』,
一個靜態方法:packing(*fruits) 靜態方法(裝箱)的思路分析 red_apple = Fruit("紅蘋果", 10) green_apple = Fruit("青蘋果", 10) yellow_banana = Fruit("黃香蕉", 8) 調用:Frulit.packing(red_apple, green_apple, yellow_banana) 打印:一箱裝了2個蘋果1個香蕉 2.自定義一個 Person 類,該類具備 name、weight、height、sex 四個對象屬性, -- 對name屬性進行封裝,可是外界任然能夠訪問name以及設置name -- 有一個方法屬性bmi(標準體重),能夠獲取一我的的bmi,bmi只讀不可寫,bmi計算規則 -- 男:(身高cm-80)× 70﹪ | 女:(身高cm-70)× 60﹪ 提示:類屬性就是直接寫在類中的變量,對象屬性就是寫在__init__方法中的用self.屬性 = 值 賦值的屬性,方法屬性就是用 @property 修飾的方法假裝成的屬性 4.用面向對象實現 植物大戰殭屍遊戲 1).定義一個殭屍Zombie類,該類能夠實例化出多種殭屍對象,殭屍對象產生默認都有 名字name、血量HP、防具armor -- 名字:普通殭屍 | 路障殭屍 | 鐵桶殭屍 -- 血量:默認就是100,不須要外界提供 -- 防具:不須要外界提供,從名字中分析肯定,防具的值是一個列表,從名字分析獲得 -- ['無', 0] | ['路障', 5] | ['鐵桶', 15] => [防具名, 防具的防護值] -- 經過@property的getter、setter方式,對外提供防具的兩個訪問接口armor_name與armor_count -- armor_name能夠取值、賦值、刪除值:經過一個 -- eg: 普通殭屍對象.armor_name = '鐵桶',不只改變了防具名 -- 普通殭屍對象的名字name也會變成 鐵桶殭屍 -- armor_count只能夠取值 2).定義一個角色User類,該類有名字name屬性、以及打殭屍的beat方法 -- 名字:隨意自定義 -- beat:該方法須要傳入一個殭屍對象 -- 在方法內部能夠實現:某某用戶攻擊了某某個殭屍,殭屍損失多少血,還剩多少血 -- 每一次攻擊,都固定扣除25滴血,可是不一樣的殭屍會被防具相應抵消掉必定的傷害值 -- 循環攻擊殭屍,3s攻擊一次,殭屍被擊殺後,打印 某某用戶擊殺了某某個殭屍 並結束方法 3).定義一個Game類,該類有一個name屬性,屬性值爲 "植物大戰殭屍" ,該類中有一個start方法,經過Game.start()來啓動遊戲 -- 遊戲一開始先顯示遊戲的名字 植物大戰殭屍遊戲 -- 會隨機產生三種殭屍,總共產生三個做爲要被擊殺的對象 -- 生成一個有角色名的角色,依次去擊殺隨機產生的每一隻殭屍 -- 開始擊殺第一隻殭屍 => 某某用戶攻擊了某某個殭屍,殭屍損失多少血,還剩多少血 => 某某用戶擊殺了某某個殭屍 => 第一隻殭屍已被擊殺完畢 => 開始擊殺第二隻殭屍 ... => 第三隻殭屍已被擊殺完畢
做業二:
角色:學校、學員、課程、講師要求:1. 建立北京、上海 2 所學校---學校2. 建立linux , python , go 3個課程 , linux\py 在北京開, go 在上海開 ----課程、地點3. 課程包含,週期,價格,經過學校建立課程-----時間、價格、4. 經過學校建立班級, 班級關聯課程、講師---班級、課程、講師5. 建立學員時,選擇學校,關聯班級 ---學員、學校、班級5. 建立講師角色時要關聯學校,---講師、學校6. 提供兩個角色接口6.1 學員視圖, 能夠註冊, 交學費, 選擇班級,---》註冊、學費、班級6.2 講師視圖, 講師可管理本身的班級, 上課時選擇班級, 查看班級學員列表 , 修改所管理的學員的成績6.3 管理視圖,建立講師, 建立班級,建立課程7. 上面的操做產生的數據都經過pickle序列化保存到文件裏