python筆記二

# 類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認爲必須綁定的屬性強制填寫進去。
# 通過定義一個特殊的__init__方法,在創建實例的時候,就把屬性綁上去
class Student(object):

    # 和普通的函數相比,在類中定義的函數只有一點不同,就是第一個參數永遠是實例變量self
    # Python解釋器自己會把實例變量傳進去
    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2
    pass
    def get_attr(self):
        print(self.attr1)

s = Student(111,222)
s.get_attr()

# 如果要讓內部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線__,
# 在Python中,實例的變量名如果以__開頭,就變成了一個私有變量(private),只有內部可以訪問,外部不能訪問

class Student(object):

    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.__attr2 = attr2
    pass

s = Student(111,222)
print(s.attr1)
print(s.__attr2)

#繼承和多態
繼承可以把父類的所有功能都直接拿過來,這樣就不必重零做起,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫     

class Parent():

    def say(self):
        print('i am parent')

# 繼承
class child(Parent):
    pass

c = child()
c.say()

# 多態 子類覆蓋了父類的同名方法 
class child2(Parent):

    def say(self):
        print('i am child')

c2 = child2()
c2.say()

# type

print(type(123))
print(type(123) == type(456)) # True
print(type(123) == int) # True
print(type('123')) # <class 'str'>

# isinstance()判斷的是一個對象是否是該類型本身,或者位於該類型的父繼承鏈上

class Hello(object):
    pass

print(isinstance(Hello, object)) # True

#類似__xxx__的屬性和方法在Python中都是有特殊用途的,
# 比如__len__方法返回長度。在Python中,如果你調用len()函數試圖獲取一個對象的長度,
# 實際上,在len()函數內部,它自動去調用該對象的__len__()方法
# 下面兩個等價
print(len('123'))
print('123'.__len__())


#不要對實例屬性和類屬性使用相同的名字,因爲相同名稱的實例屬性將屏蔽掉類屬性   
class Hello(object):
    name = 'hello'
    pass


h = Hello()
print(h.name) # hello
h.name = 'world'

print(Hello.name) # hello 類屬性
print(h.name) # world 實例屬性,屏蔽了類屬性

del h.name
print(h.name) # hello 實例屬性
print(Hello.name) # hello 類屬性


__slots__  限制給類的實例添加屬性   
class Hello(object):     
    __slots__ = ('name')  # 實例智能添加name屬性      
    pass      

h = Hello()    
h.name ='leyi'      
print(h.name) # leyi    
h.other = '123'    # 會報錯    
print(h.other) #       
  

# @property裝飾器就是負責把一個方法變成屬性調用

class Hello(object):

    def __init__(self, name):
        self.name = name;


h = Hello('leyi')
print(h.name)
# 實例可以隨意修改類的屬性,屬性沒經過校驗,這樣被認爲不安全
h.name = 'xxx'
print(h.name)


# 爲了控制屬性,我們增加方法校驗

class Hello2(object):

    def __init__(self, num = 0):
        pass

    def set_num(self, value):
        if not isinstance(value, int):
            raise ValueError('必須爲數字類型')
        if value < 100 :
            raise ValueError('必須大於等於100')
        self.num = value

    def get_num(self):
        return self.num
    pass

h2 = Hello2()
h2.set_num(121)
print(h2.get_num())


# 使用property 裝飾器簡化

class Hello3(object):

    def __init__(self, n = 0):
        pass
    @property # 將下面的方法轉換成屬性
    def num(self):
        return self.n

    # @property本身又創建了另一個裝飾器@score.setter,負責把一個setter方法變成屬性賦值
    @num.setter
    def num(self,value):
        if not isinstance(value, int):
            raise ValueError('必須爲數字類型')
        if value < 100:
            raise ValueError('必須大於等於100')
        self.n = value

    @property # 不定義setter的話,屬性就是隻讀屬性
    def num2(self):
        return self.n *12



h3 = Hello3()
h3.num = 111 # 賦值
print(h3.num) # 取屬性
# h3.num2 = 3333 # 因爲是隻讀屬性,所以賦值會報錯
print(h3.num2) # 取屬性

 
logging  \  assert     


# 文件讀寫時都有可能產生IOError,一旦出錯,
# 後面的f.close()就不會調用。所以,爲了保證無論是否出錯都能正確地關閉文件,
# 我們可以使用try ... finally來實現
try :
    f = open('./b.txt')
    print(f.read())

finally :
    if f:
        f.close()

# Python引入了with語句來自動幫我們調用close()方法

with open('./b.txt', 'r') as f1:
    print(f1.read())


# 如果文件很小,read()一次性讀取最方便;如果不能確定文件大小,
# 反覆調用read(size)比較保險;如果是配置文件,調用readlines()最方便

# 反覆調用read
def readLines():
    pos = 0
    while True :
        with open('./b.txt', 'r') as f2:
            f2.seek(pos)
            data = f2.read(4) # 反覆調用readline()也不錯
            if data:
                pos = f2.tell()
                yield data
            else:
                return

for i in readLines():
    print(i)

# 讀取所有行
with open('./b.txt', 'r') as f3:
    for l in f3.readlines():
        print(l)

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章