以上Person類繼承自object,并且有一個name屬性,Student類繼承自Person,定義了一個printInfo方法,用來打印信息,此時運行效果如下:
在python中,給變量名稱前面增加兩個下劃線,表示該變量是一個私有的變量
class Student(Person): def __init__(self,age,score): self.__age = age self.score = score def printInfo(self): print("name is :%s age is :%s score is :%s" %(self.name, self.age,self.score))上面age表示私有屬性,不能通過對象來設置值,只能在類內部操作
其實對于私有變量,也不是一定必須要通過get方法來獲取,對于上面的栗子,python解釋器將其解釋成了_Student__age,所以,我們依然可以通過這個屬性來訪問
print("age is :%s" %(student._Student__age)) # 輸出: age is :30上面我們通過self.__age = age 將age屬性表示為私有屬性,但是有的同學發現好像還是可以通過下面的代碼來設置的
student.age = 12其實這個是不對的,前面已經說過了,對于私有屬性__age,python解釋器將其解釋為_Student__age,上面的代碼,就相當于為student對象的name屬性賦值
可以使用type函數獲取當前對象的類型
print type(Student(22,50))print type(23)print type("string")print type(22.0)python中同樣提供了isinstance函數來判斷一個對象是否是一個類的實例
print isinstance(Student(22,88),Person) #輸出: Truepython中提供了setattr來為對象設置一個新的屬性,hasattr判斷是否有一個指定的屬性
student = Student(22,88)print hasattr(student,"score")setattr(student,"year","1990") # 輸出 Trueprint student.year # 輸出 1990上面的所有屬性都是通過self或者對象本身創建的屬性,這些都是對象屬性,那么同樣在python中可以創建一個類似于java中的static屬性,我們稱之為類屬性
class Student(Person): passWord = "Student pass"print("類屬性 password is :%s" %(Student.password)) # 輸出: 類屬性 password is :Student passStudent.password = "a new pass"print("類屬性 password is :%s" %(Student.password)) # 輸出: 類屬性 password is :a new pass實例屬性的優先級高于類屬性
上面使用MethodType雖然可以為實例綁定一個方法,但是這個方法對于另外一個實例是沒有效果的,比如:如果我們重新創建一個實例,并且執行上一步綁定的方法,此時會拋出如下錯誤:
studentSecond = Student(23,88)studentSecond.set_age(44)為了解決上面的問題,我們可以給整個class綁定方法,這樣該類的所有實例都可以訪問這樣的方法了
def set_age(self,age): self.age = ageStudent.set_age = set_agestudent = Student(22,88)student.name = "王五"student.printInfo()student.set_age = MethodType(set_age,student);student.set_age(44)student.printInfo()studentSecond = Student(23,88)studentSecond.set_age(55)studentSecond.printInfo()可以看到這里,我們限定當前類只能綁定age和score屬性,此時當程序試圖綁定name屬性的時候,就會出現錯誤
需要注意的是綁定屬性對于當前類的子類是沒有效果的,看下面栗子
class SubStudent(Student): passsubStudent = SubStudent()subStudent.age = 33subStudent.score = 55subStudent.name = "xiaolizi"subStudent.printInfo()print subStudent.name我們可以通過”@property”
class Student(object): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def printInfo(self): print("age is :%s score is :%s" %(self.age,self.score))student = Student()student.age = 55print student.age # 輸出: 55另外在python中是支持多繼承的,看下面的栗子
class Person(object): ''' classdocs ''' def __init__(self,name): ''' Constructor ''' self.name = nameclass MusicTeacher(Person): def learnMusic(self): print "student need to learn music"class MathTeacher(Person): def learnMath(self): print "student need to learn math"class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def printInfo(self): print("name is :%s age is :%s" %(self.name,self.age))student = Student("張三")student.age = 55student.printInfo()student.learnMath()student.learnMusic()學生會學習音樂和數學這兩門課程,此時運行效果如下:
這里之所以給”toString”添加上雙引號,是因為這里實際并不是一個toString方法,看下面栗子
class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= valuestudent = Student("張三")student.age = 55print student這里此時打印如下: 可以看到,這里和java中一樣,打印的是student實例的內存地址,不過我們可以通過添加像java中的toString方法
此時效果如下:
另外,在python中可以直接調用對象,只需要為當前類添加如下方法的實現即可:
__call__()看下面栗子:
class Student(MusicTeacher,MathTeacher): @property def age(self): return self._age @age.setter def age(self,value): self._age= value def __call__(self): print "This is student self call...."student = Student("張三")student.age = 55student()在python中,同樣支持枚舉類型,在3.6上直接支持,我的是在2.7上的實現,看下面栗子
def enum(**enums): return type('Enum', (), enums)Weeks = enum(MONDY=1, TUESDAY=2, WENSDAY='three')print str(Weeks.MONDY)+" "+str(Weeks.TUESDAY)+" "+Weeks.WENSDAY在python中,可以通過type動態創建一個類,看下面栗子
def sayHello(self): print "hello world"Hello = type('Hello', (object,), dict(sayHello=sayHello)) # 創建Hello classhello = Hello()hello.sayHello() # 輸出: hello world新聞熱點
疑難解答