Python基礎筆記(五)
1. 類(class)
下面的代碼建立了一個Employee類:
#!/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的類。正確的做法有兩種:
(1) 用“模塊名.類名“來訪問:
import Employee
tom = Employee.Employee("tom", "male", 23, 6000)
(2) 用"from...import..."的形式導入
from Employee import *
tom = Employee("tom", "male", 23, 6000)
2. 獲取對象的類型
type(obj)函數返回參數的對象類型,基本類型如int和str也可以用它來判斷:
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()判斷:
print(isinstance(23,int))
# True
print(isinstance("ABC", str))
# True
print(isinstance(b"A", bytes))
# True
print(isinstance(tom, Employee))
# True
isinstance()還可以用于判斷一個對象是否是某些類型中的一種:
print(isinstance("23", (str, int)))
# True
print(isinstance([1, 2, 3], (list, tuple)))
# True
3. 獲取對象的屬性和方法
如果要獲得一個對象的所有屬性和方法,可以使用dir(obj)函數,它返回一個包含字符串的list
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()
4. hasattr、getattr和setattr
利用這三個方法,可以判斷對象是否有某屬性/方法,獲取指定名稱的屬性/方法,新增屬性等操作:
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)

浙公網安備 33010602011771號