1. 程式人生 > 其它 >物件 繫結關係 隱藏屬性 property 繼承

物件 繫結關係 隱藏屬性 property 繼承

繫結方法兩種:

1、繫結給物件的

class Student():
  country = 'CHINA'
  
  
  def __init__(self,name,age):
    self.name = name
    self.age = age
   
  def tell_info(self):
    print('%s-30' %(self.name,self.age))
    
    
    
obj = Student('jesse',12)
obj.tell_info()

# 物件調引數,類裡面的函式tell_info本來就有引數,所以不用傳,所以是繫結說是給物件的

2、繫結給類的

類方法是繫結給類的,類來呼叫,把類名當作第一個引數傳入

# 建一個settings.py 檔案 
# 檔案內容:
# IP = '192.168.1.101'
# PORT = 3306

import settings


class Mysql():
    country = 'CHINA'

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    def tell_info(self):
        print('IP地址為:%s 埠為:%s' % (self.ip, self.port))

    @classmethod
    def from_config(cls):  # 從配置檔案匯入
        obj = cls(settings.IP, settings.PORT)
        return obj

obj = Mysql.from_config()
Mysql.tell_info(obj)
      # obj = Mysql(settings.IP,setting.PORT)
# 這裡的Mysql寫死了需要將類名寫活
# 就用到了 @classmethod裝飾器
# 這個裝飾器將:
# Mysql.from_config()  前面的類名傳到函式括號裡面
obj = Mysql.from_config()
Mysql.tell_info(obj)

注意如果發生既想繫結給物件又想繫結給類的情況我們就直接將它繫結給物件,讓後用self.___class_方法 來繫結給類

非繫結方法

即不繫結給物件,也不繫結給類

先小小了解一下uuip模組

import uuid
print(uuid.uuid4())
# 會隨機生成一串字串
class Mysql():
  def __init__(self,ip,port):
    self.ip = ip
    self.port = port
    
  @staticmethod # 靜態方法
  def create_id():
    # 這裡下面沒有需要用到物件的程式碼
    # 所以這裡是可以沒有self的
    # 但我們呼叫的時候用到了物件
    # 我們可以用@staticmethod裝飾器裝飾一下
    # 後面就可以用物件呼叫它了
   
    import uuid
    print(uuid.uuid4())
    
    
obj = Mysql('127.0.0.1',3306)
obj.create_id()
Mysql.creat_id()  # 我們發現用類也可以呼叫了

# 這就是非繫結方法

引數用不到可以不用傳,這就是非繫結方法

隱藏屬性

1、如何隱藏屬性?

class People():
  __country = 'CHINA'  # 在前面加__該屬性就被隱藏了
  
  
  def __init__(self,name,age)
  	self.name = name
    self.age = age
    
 obj = People('ly',18)   
# 被隱藏就取不到了
print(People.__dict__) # 檢視類裡面的屬性
# 會發現隱藏的__country 變成了_People__country
# 語法上在定義階段進行了變形

# print(People._People__country) 這樣就可以取出來了,但這樣取就比較麻煩
# 刪除和上面同理

該隱藏對外不對內,因為在函式定義階段發生了變形,那所以包含該屬性的程式碼也同時發生了變形。所以雖然在外部取不到,但是我們可以在寫一個呼叫該屬性的方法。

class People():
  __country = 'CHINA'  
  
  def __init__(self,name,age)
  	self.name = name
    self.age = age
    
    
  def get_country(self):
    return '國家:%s'% self.__country
    
obj = People('ly',18)

2、為什麼要隱藏

該隱藏對外不對內,如果想訪問類中隱藏屬性,在類中開放對外訪問的介面,可以更好的對外部做限制

class People():
  __country = 'CHINA'  
  
  def __init__(self,name,age)
  	self.name = name
    self.age = age
    
    
  def get_country(self):
    return '國家:%s'% self.__countr
  
  
  def set_country(self,v):
  	if not type(v) is str:
      print('country必須是str型別')
      return
    self.__country = v
  # 對更改作出限制  
  def del_country(self):
    print('不能刪除')
   

peoperty裝飾器

裝飾器:裝飾器實在不修改被張是物件原始碼以及呼叫方式的前提下為被裝飾物件新增新功能的可呼叫物件

'''
成人的BMI數值:
過輕:低於18.5
正常:18.5-23.9
過重:24-27
肥胖:28-32
非常肥胖,高於32
  體質指數(BMI)= 體重(kg) ➗ 身高^2(m)
'''

class People():
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    def bmi(self):
        return self.weight / self.height ** 2


obj1 = People('jesse', 65, 1.75)
print(obj1.bmi())
  

property是一個裝飾器,是用來繫結給物件的方法偽裝成一個數據屬性

class People():
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height
		@property
    def bmi(self):
        return self.weight / self.height ** 2


obj1 = People('jesse', 65, 1.75)
print(obj1.bmi) # 加了property裝飾器之後呼叫就不需要加括號

property的另一個語法,針對隱藏屬性的操作,能夠讓使用者查詢不到

class Student():
  __school = '十三中'  # 將學校屬性隱藏起來
  def __init__(self,name,age,gender):
    self.name = name
    self.age = age
    self.gender = gender
    
  def get_school(self):
    return self.__school
  
  
  def set_school(self,v)
    if not type(v) is str:
      print('學校名稱必須為字串')
     	return
    self.name = v
    
  def del_school(self):
    print('不可以刪除學校名稱')
    
    
  school = property(get_school,set_school,del_school)
# 將這些功能 加上property語法賦值給一個變數名,就可以通過變數名來進行操作了

obj1 = People('jesse','16','mael')

print(obj1.school)  # 這樣就能取出學校名字了相當於之前沒加property的 print(obj1.get_school)

obj1.school = '十八中' # property 會檢測語法,察覺到這是更改操作就會執行 obj1.set_school = '十八中'

del obj1.school # 也是同理

還有一種用法,和上面用法一樣

class Student():
  __school = '十三中'  # 將學校屬性隱藏起來
  def __init__(self,name,age,gender):
    self.name = name
    self.age = age
    self.gender = gender
    
  @property  # 相當於 school = property(school)
  def school(self):
    return self.__school
  
  @school.setter
  def school(self,v)
    if not type(v) is str:
      print('學校名稱必須為字串')
     	return
    self.name = v
  @school.deleter 
  def school(self):
    print('不可以刪除學校名稱')
    
# 加裝飾器用法  
1、先將所有功能函式名稱定義成要偽裝呼叫的函式名稱,比如這裡面我們就用school 
2.在get_school功能上加一個property裝飾器
  在set_school功能上 @school.setter
  在school.del功能上 @school.deleter

推薦用這種加裝飾器的方式,更加清晰

繼承

1、什麼是繼承

繼承是一種建立新類的方式,新建的類可稱為子類或派生類,父類又可以稱之為基類或超類

在Python這門語言中是支援多繼承的,即新建的類可以繼承一個或多個父類

class Parent1:
  pass


class Parent2:
  pass
  

class Sub1(Parent1): # 單繼承
  pass


class Sub2(Parent1,Parent2): # 多繼承
  pass

print(Sub1.__bases__)
print(Sub2.__bases__)

在Python2中有經典類與新式類之分

新式類:繼承了object類的子類,以及該子類的子類等

經典類:沒有繼承object類的子類,以及該子類的子類等

在Python3中沒有繼承任何類,那麼就會預設繼承object,所以Python中只有新式類

子類中沒有的屬性會去父類那找,

python的多繼承:

優點:子類可以同時遺傳多個父類的屬性,最大限度的重用程式碼

缺點:程式碼可讀性擴張性會變差,不建議使用多繼承,如果一定要用,應該用使用Mixins

2、為什麼要用繼承

用來解決類與類之間程式碼冗餘的問題,將共有的東西提取到父類當中

3、如何使用繼承

class All_people():
  school = '清華大學'
  def __init__(self,name,age,gender):
    self.name = name
    self.age = age
    self.gender = gender

class Student(All_people):
  def choose_course(self):
    print('學生 %s 正在選課' %self.name)
    
    
    
    
class Teacher(All_people):
	
  def __init__(self,name,age,gender,courses):
    All_people.__init__(self,name,age,sex)
    self.courses = courses
    
    
stu_obj = Student('jesse','18','male')
print(stu_obj.school)