下面的代碼創建了一個Employee類:python
#!/usr/bin/env python3 # -*- coding: utf-8 -*- class Employee(object): company = "IBM" def __init__(self, name, sex, age, salary): self.name = name self.sex = sex self.age = age self.__salary = salary def getSignature(self): signature = "My name is %s, I'm %d years old." % (self.name, self.age) return signature def getSalary(self): return self.__salary def setSalary(self, salary): if 0 < salary <= 10000: self.__salary = salary else: raise ValueError("Invalid Value") tom = Employee("tom", "male", 23, 3000) print(tom.getSignature()) # My name is tom, I'm 23 years old. print(tom.age) # 23 tom.setSalary(5000) tom.__salary = 9000 # 無效,實際上是新增了一個名爲"__salary"的變量 print(tom.getSalary()) # 5000
__init__
方法至關於其它語言的「構造函數」,該方法的第一個參數必須爲self,self表明建立的實例自己,所以在__init__
方法內部能夠把各類屬性綁定到self;在實際調用時,self並不須要傳遞,Python解釋器本身會把實例變量傳進去。
以一個下劃線開頭的變量名,例如_company
,這種變量外部是能夠訪問的,可是按照約定俗成的規定,這種變量應該視爲私有變量,不要隨意訪問。
以兩個下劃線開頭的變量名,例如__salary
,是私有變量,外部不能直接訪問,通常提供"get"和"set"方法去間接獲取和修改。
開頭與結尾都是兩個下劃線,例如__name__
,是特殊變量,特殊變量是能夠直接訪問的。
須要注意的是,當在一個外部類嘗試用下面的代碼訪問新建的Employee類時,是會報錯的:函數
import Employee tom = Employee("tom", "female", "23")
報錯內容爲TypeError: 'module' object is not callable
,這個錯誤是指試圖把模塊做爲一個函數來調用。產生錯誤的緣由是,import Emplyee
實際上是導入了整個的Employee.py
,而不是名爲Employee
的類。正確的作法有兩種:ui
(1) 用「模塊名.類名「來訪問:code
import Employee tom = Employee.Employee("tom", "male", 23, 6000)
(2) 用"from...import..."的形式導入對象
from Employee import * tom = Employee("tom", "male", 23, 6000)
type(obj)
函數返回參數的對象類型,基本類型如int
和str
也能夠用它來判斷:utf-8
from Employee import * tom = Employee("tom", "male", 23, 6000) print(type(23)) # <class 'int'> print(type("ABC")) # <class 'str'> print(type(tom)) # <class 'Employee.Employee'> if type(123) == type(456): print("Equal") if type("ABC") == str: print("Equal") print(type(tom) == Employee) # True
可使用types模塊中定義的常量來判斷一個對象是不是函數,lambda函數或generator:字符串
import types def myFun(): pass # 是不是函數 print(type(myFun) == types.FunctionType) # True # 是不是內置函數 print(type(abs) == types.BuiltinFunctionType) # True # 是不是lambda函數 print(type(lambda x: x)==types.LambdaType) # True # 是不是generator print(type((x for x in range(10)))==types.GeneratorType) # True
能用type()判斷的基本類型也能夠用isinstance()判斷:get
print(isinstance(23,int)) # True print(isinstance("ABC", str)) # True print(isinstance(b"A", bytes)) # True print(isinstance(tom, Employee)) # True
isinstance()還能夠用於判斷一個對象是不是某些類型中的一種:generator
print(isinstance("23", (str, int))) # True print(isinstance([1, 2, 3], (list, tuple))) # True
若是要得到一個對象的全部屬性和方法,可使用dir(obj)
函數,它返回一個包含字符串的listit
print(dir("ABC")) # ['__add__', '__class__', ... , 'upper', 'zfill']
相似__xxx__的屬性和方法在Python中都是有特殊用途的,好比__len__方法返回長度。在Python中,若是你調用len()函數試圖獲取一個對象的長度,實際上,在len()函數內部,它自動去調用該對象的__len__()方法,因此,下面的代碼是等價的:
print(len("ABC")) print("ABC".__len__())
下面的例子證實了len()會調用__len__()方法:
class MyClass1(object): def __len__(self): return 100 class MyClass2(object): pass myClass = MyClass1() print(len(myClass)) # 100 myClass = MyClass2() print(len(myClass)) # TypeError: object of type 'MyClass2' has no len()
利用這三個方法,能夠判斷對象是否有某屬性/方法,獲取指定名稱的屬性/方法,新增屬性等操做:
class Employee(object): def __init__(self, name, sex, age, salary): self.name = name self.sex = sex self.age = age self.__salary = salary def getSignature(self): signature = "My name is %s, I'm %d years old." % (self.name, self.age) return signature employee = Employee("tom", "male", 23, 3000) # 判斷對象是否有"age"屬性,有則打印並賦值 if hasattr(employee, "age"): print(employee.age) employee.age = 18 # 若是對象沒有"hobby"屬性,則新增該屬性並賦值 if not hasattr(employee, "hobby"): setattr(employee, "hobby", "music") # 經過getattr獲取對象指定的屬性值 print(getattr(employee, "hobby")) # music # 若是試圖獲取不存在的屬性,會拋出AttributeError的錯誤: # getattr(employee, "gold") # AttributeError: 'Employee' object has no attribute 'gold' # 利用getattr的第三個參數:若是屬性不存在,就返回一個默認值 print(getattr(employee, "gold", "not exist")) # not exist # 經過getattr獲取方法,注意:若是方法不存在,會拋出AttributeError print(getattr(employee, "getSignature")) # <bound method Employee.getSalary of <__main__.Employee object at 0x10832a4a8>> # 判斷是否存在指定名稱的方法,若是存在,則執行該方法 try: funcName = "getSignature" func = getattr(employee, funcName) if hasattr(func, "__call__"): print("存在方法", funcName) # 存在方法 getSignature print(func()) # My name is tom, I'm 18 years old. except AttributeError as e: print("沒有方法:", funcName)