Python—初識面向對象

来源:https://www.cnblogs.com/Golanguage/archive/2020/02/16/12315605.html
-Advertisement-
Play Games

楔子 你現在是一家游戲公司的開發人員,現在需要你開發一款叫做<人狗大戰>的游戲,你就思考呀,人狗作戰,那至少需要2個角色,一個是人, 一個是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎麼描述這種不同的角色和他們的功能呢? 你搜羅了自己掌握的所有技能,寫出了下麵的代碼來描述這兩個角色 ...


楔子

你現在是一家游戲公司的開發人員,現在需要你開發一款叫做<人狗大戰>的游戲,你就思考呀,人狗作戰,那至少需要2個角色,一個是人, 一個是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎麼描述這種不同的角色和他們的功能呢? 你搜羅了自己掌握的所有技能,寫出了下麵的代碼來描述這兩個角色
def person(name,age,sex,job):
    data = {
        'name':name,
        'age':age,
        'sex':sex,
        'job':job
    }
 
    return data
 
def dog(name,dog_type):
    data = {
        'name':name,
        'type':dog_type
    }
    return data

上面兩個方法相當於造了兩個模子,游戲里的每個人和每條狗都擁有相同里的屬性。游戲開始,你根據一個人或一隻狗傳入的具體信息來塑造一個具體的人或者狗,怎麼生成呢?

d1 = dog("李磊","京巴")
p1 = person("嚴帥",36,"F","運維")
p2 = person("egon",27,"F","Teacher")

兩個角色對象生成了,狗和人還有不同的功能呀,狗會咬人,人會打狗,對不對? 怎麼實現呢,。。想到了, 可以每個功能再寫一個函數,想執行哪個功能,直接 調用 就可以了,對不?

def bark(d):
    print("dog %s:wang.wang..wang..."%d['name'])
 
 
def walk(p):
    print("person %s is walking..." %p['name'])<br><br>
walk(p1) 
bark(d1)

上面的功能實現的簡直是完美!

但是仔細玩耍一會,你就不小心幹了下麵這件事

p1 = person("嚴帥",36,"F","運維")
bark(p1) #把人的對象傳給了狗的方法

事實 上,從你寫的代碼上來看,這並沒出錯。很顯然,人是不能調用狗的功能的,但在你的程式例沒有做限制,如何在代碼級別實現這個限制呢?

def person(name,age,sex,job):
    def walk(p):
        print("person %s is walking..." % p['name'])
 
    data = {
        'name':name,
        'age':age,
        'sex':sex,
        'job':job,
        'walk':walk
    }
 
    return data
 
def dog(name,dog_type):
 
 
    def bark(d):
        print("dog %s:wang.wang..wang..."%d['name'])
    data = {
        'name':name,
        'type':dog_type,
        'bark':bark
    }
 
    return data
限制功能全新代碼
d1 = dog("李磊","京巴")
p1 = person("嚴帥",36,"F","運維")
p2 = person("egon",27,"F","Teacher")
生產具體的人和汪
d1['bark'](p1) #把人傳給了狗的方法
無法調用了

你是如此的機智,這樣就實現了限制人只能用人自己的功能啦。

剛剛你用的這種編程思想其實就是簡單的面向對象編程,我們創造了兩個模子表示游戲里所有的人和狗之後,剩下的狗叫或者人走對於這兩個模子來說就不重要了。具體人he狗之間的交互就等著你去使用了。假如你和狗打起來了,這時候你是走路還是拿棍子打狗就由你自己決定了。那你的每一個決定可能都影響著你這場游戲的輸贏。這也是不確定的。和我們之前寫代碼按部就班的走,最終都會實現我們要完成的事情不太一樣了。

儘管如此,我們也只完成了這個游戲非常小的一部分。還有很多功能都沒有實現。

剛纔你只是阻止了兩個完全 不同的角色 之前的功能混用, 但有沒有可能 ,同一個種角色,但有些屬性是不同的呢? 比如 ,大家都打過cs吧,cs里有警察和恐怖份子,但因為都 是人, 所以你寫一個角色叫 person(), 警察和恐怖份子都 可以 互相射擊,但警察不可以殺人質,恐怖分子可以,這怎麼實現呢? 你想了說想,說,簡單,只需要在殺人質的功能裡加個判斷,如果是警察,就不讓殺不就ok了麽。 沒錯, 這雖然 解決了殺人質的問題,但其實你會發現,警察和恐怖分子的區別還有很多,同時又有很多共性,如果 在每個區別處都 單獨做判斷,那得累死。 

你想了想說, 那就直接寫2個角色吧, 反正 這麼多區別, 我的哥, 不能寫兩個角色呀,因為他們還有很多共性 , 寫兩個不同的角色,就代表 相同的功能 也要重寫了,是不是我的哥? 。。。

好了, 話題就給你點到這, 再多說你的智商也理解不了了!

面向過程 VS 面向對象

面向過程的程式設計的核心是過程(流水線式思維),過程即解決問題的步驟,面向過程的設計就好比精心設計好一條流水線,考慮周全什麼時候處理什麼東西。

優點是:極大的降低了寫程式的複雜度,只需要順著要執行的步驟,堆疊代碼即可。

缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一發而動全身。

應用場景:一旦完成基本很少改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

 

面向對象的程式設計的核心是對象(上帝式思維),要理解對象為何物,必須把自己當成上帝,上帝眼裡世間存在的萬物皆為對象,不存在的也可以創造出來。面向對象的程式設計好比如來設計西游記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題需要四個人:唐僧,沙和尚,豬八戒,孫悟空,每個人都有各自的特征和技能(這就是對象的概念,特征和技能分別對應對象的屬性和方法),然而這並不好玩,於是如來又安排了一群妖魔鬼怪,為了防止師徒四人在取經路上被搞死,又安排了一群神仙保駕護航,這些都是對象。然後取經開始,師徒四人與妖魔鬼怪神仙互相纏鬥著直到最後取得真經。如來根本不會管師徒四人按照什麼流程去取。

面向對象的程式設計的

優點是:解決了程式的擴展性。對某一個對象單獨修改,會立刻反映到整個體系中,如對游戲中一個人物參數的特征和技能修改都很容易。

缺點:可控性差,無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,面向對象的程式一旦開始就由對象之間的交互解決問題即便是上帝也無法預測最終結果。於是我們經常看到一個游戲人某一參數的修改極有可能導致陰霸的技能出現,一刀砍死3個人,這個游戲就失去平衡。

應用場景:需求經常變化的軟體,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟體,游戲等都是面向對象的程式設計大顯身手的好地方。

在python 中面向對象的程式設計並不是全部。

面向對象編程可以使程式的維護和擴展變得更簡單,並且可以大大提高程式開發效率 ,另外,基於面向對象的程式可以使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。

瞭解一些名詞:類、對象、實例、實例化

類:具有相同特征的一類事物(人、狗、老虎)

對象/實例:具體的某一個事物(隔壁阿花、樓下旺財)

實例化:類——>對象的過程(這在生活中表現的不明顯,我們在後面再慢慢解釋)

初識類和對象

python中一切皆為對象,類型的本質就是類,所以,不管你信不信,你已經使用了很長時間的類了

>>> dict #類型dict就是類dict
<class 'dict'>
>>> d=dict(name='eva') #實例化
>>> d.pop('name') #向d發一條消息,執行d的方法pop
'eva'

從上面的例子來看,字典就是一類數據結構,我一說字典你就知道是那個用{}表示,裡面由k-v鍵值對的東西,它還具有一些增刪改查的方法。但是我一說字典你能知道字典里具體存了哪些內容麽?不能,所以我們說對於一個類來說,它具有相同的特征屬性和方法。

而具體的{'name':'eva'}這個字典,它是一個字典,可以使用字典的所有方法,並且裡面有了具體的值,它就是字典的一個對象。對象就是已經實實在在存在的某一個具體的個體。

 

再舉一個其他的例子,通俗一點,比如你現在有一個動物園,你想描述這個動物園,那麼動物園裡的每一種動物就是一個類,老虎、天鵝、鱷魚、熊。他們都有相同的屬性,比如身高體重出生時間和品種,還有各種動作,比如鱷魚會游泳,天鵝會飛,老虎會跑,熊會吃。

但是這些老虎熊啥的都不是具體的某一隻,而是一類動物。雖然他們都有身高體重,但是你卻沒有辦法確定這個值是多少。如果這個時候給你一隻具體的老虎,而你還沒死,那你就能給他量量身高稱稱體重,這些數值是不是就變成具體的了?那麼具體的這一隻老虎就是一個具體的實例,也是一個對象。不止這一隻,其實每一隻具體的老虎都有自己的身高體重,那麼每一隻老虎都是老虎類的一個對象。

在python中,用變數表示特征,用函數表示技能,因而具有相同特征和技能的一類事物就是‘類’,對象是則是這一類事物中具體的一個。

類的相關知識

初識類

聲明
def functionName(args):
     '函數文檔字元串'
      函數體 
'''
class 類名:
    '類的文檔字元串'
    類體
'''

#我們創建一個類
class Data:
    pass
class Person:   #定義一個人類
    role = 'person'  #人的角色屬性都是人
    def walk(self):  #人都可以走路,也就是有一個走路方法,也叫動態屬性
        print("person is walking...")

類有兩種作用:屬性引用和實例化

 屬性引用(類名.屬性)
class Person:   #定義一個人類
    role = 'person'  #人的角色屬性都是人
    def walk(self):  #人都可以走路,也就是有一個走路方法
        print("person is walking...")


print(Person.role)  #查看人的role屬性
print(Person.walk)  #引用人的走路方法,註意,這裡不是在調用
實例化

類名加括弧就是實例化,會自動觸發__init__函數的運行,可以用它來為每個實例定製自己的特征

class Person:   #定義一個人類
    role = 'person'  #人的角色屬性都是人
    def __init__(self,name):
        self.name = name  # 每一個角色都有自己的昵稱;
        
    def walk(self):  #人都可以走路,也就是有一個走路方法
        print("person is walking...")


print(Person.role)  #查看人的role屬性
print(Person.walk)  #引用人的走路方法,註意,這裡不是在調用

實例化的過程就是類——>對象的過程

原本我們只有一個Person類,在這個過程中,產生了一個egg對象,有自己具體的名字、攻擊力和生命值。

語法:對象名 = 類名(參數)

egg = Person('egon')  #類名()就等於在執行Person.__init__()
#執行完__init__()就會返回一個對象。這個對象類似一個字典,存著屬於這個人本身的一些屬性和方法。
查看屬性&調用方法
print(egg.name)     #查看屬性直接 對象名.屬性名
print(egg.walk())   #調用方法,對象名.方法名()
關於self

self:在實例化時自動將對象/實例本身傳給__init__的第一個參數,你也可以給他起個別的名字,但是正常人都不會這麼做。
因為你瞎改別人就不認識

類屬性的補充
一:我們定義的類的屬性到底存到哪裡了?有兩種方式查看
dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key為屬性名,value為屬性值

二:特殊的類屬性
類名.__name__# 類的名字(字元串)
類名.__doc__# 類的文檔字元串
類名.__base__# 類的第一個父類(在講繼承時會講)
類名.__bases__# 類所有父類構成的元組(在講繼承時會講)
類名.__dict__# 類的字典屬性
類名.__module__# 類定義所在的模塊
類名.__class__# 實例對應的類(僅新式類中)
 

對象的相關知識

回到咱們的人狗大戰:現在我們需要對我們的類做出一點點改變
人類除了可以走路之外,還應該具備一些攻擊技能。

class Person:  # 定義一個人類
    role = 'person'  # 人的角色屬性都是人

    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 每一個角色都有自己的昵稱;
        self.aggressivity = aggressivity  # 每一個角色都有自己的攻擊力;
        self.life_value = life_value  # 每一個角色都有自己的生命值;

    def attack(self,dog):  
        # 人可以攻擊狗,這裡的狗也是一個對象。
        # 人攻擊狗,那麼狗的生命值就會根據人的攻擊力而下降
        dog.life_value -= self.aggressivity

對象是關於類而實際存在的一個例子,即實例

對象/實例只有一種作用:屬性引用

egg = Person('egon',10,1000)
print(egg.name)
print(egg.aggressivity)
print(egg.life_value)

當然了,你也可以引用一個方法,因為方法也是一個屬性,只不過是一個類似函數的屬性,我們也管它叫動態屬性。
引用動態屬性並不是執行這個方法,要想調用方法和調用函數是一樣的,都需要在後面加上括弧

print(egg.attack)

我知道在類里說,你可能還有好多地方不能理解。那我們就用函數來解釋一下這個類呀,對象呀到底是個啥,你偷偷的用這個理解就好了,不要告訴別人

def Person(*args,**kwargs):
    self = {}
    def attack(self,dog):
        dog['life_value'] -= self['aggressivity']

    def __init__(name,aggressivity,life_value):
        self['name'] = name
        self['aggressivity'] = aggressivity
        self['life_value'] = life_value
        self['attack'] = attack

    __init__(*args,**kwargs)
    return self

egg = Person('egon',78,10)
print(egg['name'])

面向對象小結——定義及調用的固定模式

class 類名:
    def __init__(self,參數1,參數2):
        self.對象的屬性1 = 參數1
        self.對象的屬性2 = 參數2

    def 方法名(self):pass

    def 方法名2(self):pass

對象名 = 類名(1,2)  #對象就是實例,代表一個具體的東西
                  #類名() : 類名+括弧就是實例化一個類,相當於調用了__init__方法
                  #括弧里傳參數,參數不需要傳self,其他與init中的形參一一對應
                  #結果返回一個對象
對象名.對象的屬性1   #查看對象的屬性,直接用 對象名.屬性名 即可
對象名.方法名()     #調用類中的方法,直接用 對象名.方法名() 即可
練習一:在終端輸出如下信息

小明,10歲,男,上山去砍柴
小明,10歲,男,開車去東北
小明,10歲,男,最愛大保健
老李,90歲,男,上山去砍柴
老李,90歲,男,開車去東北
老李,90歲,男,最愛大保健
老張…

對象之間的交互

現在我們已經有一個人類了,通過給人類一些具體的屬性我們就可以拿到一個實實在在的人。
現在我們要再創建一個狗類,狗就不能打人了,只能咬人,所以我們給狗一個bite方法。
有了狗類,我們還要實例化一隻實實在在的狗出來。
然後人和狗就可以打架了。現在我們就來讓他們打一架吧!

創建一個狗類

class Dog:  # 定義一個狗類
    role = 'dog'  # 狗的角色屬性都是狗

    def __init__(self, name, breed, aggressivity, life_value):
        self.name = name  # 每一隻狗都有自己的昵稱;
        self.breed = breed  # 每一隻狗都有自己的品種;
        self.aggressivity = aggressivity  # 每一隻狗都有自己的攻擊力;
        self.life_value = life_value  # 每一隻狗都有自己的生命值;

    def bite(self,people):
        # 狗可以咬人,這裡的狗也是一個對象。
        # 狗咬人,那麼人的生命值就會根據狗的攻擊力而下降
     dog.life_value -= self.aggressivit

實例化一隻實實在在的二哈

ha2 = Dog('二愣子','哈士奇',10,1000)  #創造了一隻實實在在的狗ha2

交互 egon打ha2一下

print(ha2.life_value)         #看看ha2的生命值
egg.attack(ha2)               #egg打了ha2一下
print(ha2.life_value)         #ha2掉了10點血

完整的代碼

class Person:  # 定義一個人類
    role = 'person'  # 人的角色屬性都是人

    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 每一個角色都有自己的昵稱;
        self.aggressivity = aggressivity  # 每一個角色都有自己的攻擊力;
        self.life_value = life_value  # 每一個角色都有自己的生命值;

    def attack(self,dog):
        # 人可以攻擊狗,這裡的狗也是一個對象。
        # 人攻擊狗,那麼狗的生命值就會根據人的攻擊力而下降
        dog.life_value -= self.aggressivity

class Dog:  # 定義一個狗類
    role = 'dog'  # 狗的角色屬性都是狗

    def __init__(self, name, breed, aggressivity, life_value):
        self.name = name  # 每一隻狗都有自己的昵稱;
        self.breed = breed  # 每一隻狗都有自己的品種;
        self.aggressivity = aggressivity  # 每一隻狗都有自己的攻擊力;
        self.life_value = life_value  # 每一隻狗都有自己的生命值;

    def bite(self,people):
        # 狗可以咬人,這裡的狗也是一個對象。
        # 狗咬人,那麼人的生命值就會根據狗的攻擊力而下降
        people.life_value -= self.aggressivity

egg = Person('egon',10,1000)  #創造了一個實實在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000)  #創造了一隻實實在在的狗ha2
print(ha2.life_value)         #看看ha2的生命值
egg.attack(ha2)               #egg打了ha2一下
print(ha2.life_value)         #ha2掉了10點血
egon大戰哈士奇
from math import pi

class Circle:
    '''
    定義了一個圓形類;
    提供計算面積(area)和周長(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #實例化一個圓
area1 = circle.area() #計算圓面積
per1 = circle.perimeter() #計算圓周長
print(area1,per1) #列印圓面積和周長
一個簡單的例子幫你理解面向對象

類命名空間與對象、實例的命名空間

創建一個類就會創建一個類的名稱空間,用來存儲類中定義的所有名字,這些名字稱為類的屬性

而類有兩種屬性:靜態屬性和動態屬性

  • 靜態屬性就是直接在類中定義的變數
  • 動態屬性就是定義在類中的方法

類的數據屬性是共用給所有對象的

>>>id(egg.role)
4341594072
>>>id(Person.role)
4341594072

而類的動態屬性是綁定到所有對象的

>>>egg.attack
<bound method Person.attack of <__main__.Person object at 0x101285860>>
>>>Person.attack
<function Person.attack at 0x10127abf8> 

創建一個對象/實例就會創建一個對象/實例的名稱空間,存放對象/實例的名字,稱為對象/實例的屬性

在obj.name會先從obj自己的名稱空間里找name,找不到則去類中找,類也找不到就找父類...最後都找不到就拋出異常

面向對象的組合用法

軟體重用的重要方式除了繼承之外還有另外一種方式,即:組合

組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組合

class Weapon:
    def prick(self, obj):  # 這是該裝備的主動技能,扎死對方
        obj.life_value -= 500  # 假設攻擊力是500

class Person:  # 定義一個人類
    role = 'person'  # 人的角色屬性都是人

    def __init__(self, name):
        self.name = name  # 每一個角色都有自己的昵稱;
        self.weapon = Weapon()  # 給角色綁定一個武器;
        
egg = Person('egon')
egg.weapon.prick() 
#egg組合了一個武器的對象,可以直接egg.weapon來使用組合類中的所有方法

圓環是由兩個圓組成的,圓環的面積是外面圓的面積減去內部圓的面積。圓環的周長是內部圓的周長加上外部圓的周長。
這個時候,我們就首先實現一個圓形類,計算一個圓的周長和麵積。然後在"環形類"中組合圓形的實例作為自己的屬性來用

from math import pi

class Circle:
    '''
    定義了一個圓形類;
    提供計算面積(area)和周長(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #實例化一個圓
area1 = circle.area() #計算圓面積
per1 = circle.perimeter() #計算圓周長
print(area1,per1) #列印圓面積和周長

class Ring:
    '''
    定義了一個圓環類
    提供圓環的面積和周長的方法
    '''
    def __init__(self,radius_outside,radius_inside):
        self.outsid_circle = Circle(radius_outside)
        self.inside_circle = Circle(radius_inside)

    def area(self):
        return self.outsid_circle.area() - self.inside_circle.area()

    def perimeter(self):
        return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()


ring = Ring(10,5) #實例化一個環形
print(ring.perimeter()) #計算環形的周長
print(ring.area()) #計算環形的面積

用組合的方式建立了類與組合的類之間的關係,它是一種‘有’的關係,比如教授有生日,教授教python課程

class BirthDate:
def __init__(self,year,month,day): self.year=year self.month=month self.day=day class Couse: def __init__(self,name,price,period): self.name=name self.price=price self.period=period class Teacher: def __init__(self,name,gender,birth,course):
        self.name=name 
self.gender=gender
self.birth=birth
self.course=course
    def teach(self): 
print('teaching')

p1=Teacher('egon','male', 
BirthDate('1995','1','27'),
Couse('python','28000','4 months')
)

print(p1.birth.year,p1.birth.month,p1.birth.day)

print(p1.course.name,p1.course.price,p1.course.period)
'''
運行結果:
1 27
python 28000 4 months
'''

當類之間有顯著不同,並且較小的類是較大的類所需要的組件時,用組合比較好

初識面向對象小結

定義一個人類

class Person:  # 定義一個人類
    role = 'person'  # 人的角色屬性都是人

    def __init__(self, name, aggressivity, life_value, money):
        self.name = name  # 每一個角色都有自己的昵稱;
        self.aggressivity = aggressivity  # 每一個角色都有自己的攻擊力;
        self.life_value = life_value  # 每一個角色都有自己的生命值;
        self.money = money

    def attack(self,dog):
        # 人可以攻擊狗,這裡的狗也是一個對象。
        # 人攻擊狗,那麼狗的生命值就會根據人的攻擊力而下降
dog.life_value -= self.aggressivity

定義一個狗類

class Dog:  # 定義一個狗類
    role = 'dog'  # 狗的角色屬性都是狗

    def __init__(self, name, breed, aggressivity, life_value):
        self.name = name  # 每一隻狗都有自己的昵稱;
        self.breed = breed  # 每一隻狗都有自己的品種;
        self.aggressivity = aggressivity  # 每一隻狗都有自己的攻擊力;
        self.life_value = life_value  # 每一隻狗都有自己的生命值;

    def bite(self,people):
        # 狗可以咬人,這裡的狗也是一個對象。
        # 狗咬人,那麼人的生命值就會根據狗的攻擊力而下降
        people.life_value -= self.aggressivity

接下來,又創建一個新的兵器類。

class Weapon:
    def __init__(self,name, price, aggrev, life_value):
        self.name = name
        self.price = price
        self.aggrev = aggrev
        self.life_value = life_value

    def update(self, obj):  #obj就是要帶這個裝備的人
        obj.money -= self.price  # 用這個武器的人花錢買所以對應的錢要減少
        obj.aggressivity += self.aggrev  # 帶上這個裝備可以讓人增加攻擊
        obj.life_value += self.life_value  # 帶上這個裝備可以讓人增加生命值

    def prick(self, obj):  # 這是該裝備的主動技能,扎死對方
        obj.life_value -= 500  # 假設攻擊力是500

測試交互

lance = Weapon('長矛',200,6,100)
egg = Person('egon',10,1000,600)  #創造了一個實實在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000)  #創造了一隻實實在在的狗ha2

#egg獨自力戰"二愣子"深感吃力,決定窮畢生積蓄買一把武器
if egg.money > lance.price: #如果egg的錢比裝備的價格多,可以買一把長矛
    lance.update(egg) #egg花錢買了一個長矛防身,且自身屬性得到了提高
    egg.weapon = lance #egg裝備上了長矛

print(egg.money,egg.life_value,egg.aggressivity)

print(ha2.life_value)
egg.attack(ha2)   #egg打了ha2一下
print(ha2.life_value)
egg.weapon.prick(ha2) #發動武器技能
print(ha2.life_value) #ha2不敵狡猾的人類用武器取勝,血槽空了一半

按照這種思路一點一點的設計類和對象,最終你完全可以實現一個對戰類游戲。

使用types模塊確認方法和函數的區別
使用pickle存取自定義類的對象的

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 盒模型規定了元素框處理元素內容width與height值、內邊距padding、邊框border 和 外邊距margin 的數值大小。邊框內的空白是內邊距padding,邊框外的空白是外邊距margin,如下所示,這個盒模型元素框的寬度值=內容區域的寬度+2(內邊距+外邊距+邊框),也就是該示例中的... ...
  • 能找到一份前端開發工作,首先你起碼得是一個合格的初級前端工程師。那麼,什麼是初級前端工程師?初級前端工程師都會做些什麼?這個問題需要分為以下幾個方面來說: ...
  • 前言 現在的前端門檻越來越高,不再是只會寫寫頁面那麼簡單。模塊化、自動化、跨端開發等逐漸成為要求,但是這些都需要建立在我們牢固的基礎之上。不管框架和模式怎麼變,把基礎原理打牢才能快速適應市場的變化。下麵介紹一些常用的源碼實現: call實現 bind實現 new實現 instanceof實現 Obj ...
  • 前言 昨天一番發了一篇批量下載手機壁紙的文章,分享了抓取到的美圖給小伙伴,然後一番就美美的去碎覺了。 早上起來看到有小伙伴在日更群里說有沒有狗哥的?憨憨的一番以為就是狗的圖片,於是就發了幾張昨天抓取的狗的圖片。 在群友的幫助下,一番才知道是愛情公寓里的一個演員。 小伙伴有需求,一番本著力所能及的幫助 ...
  • 時間輪演算法 時間輪是一種高效、低延遲的調度數據結構。其在Linux內核中廣泛使用,是Linux內核定時器的實現方法和基礎之一。按使用場景,大致可以分為兩種時間輪:原始時間輪和分層時間輪。分層時間輪是原始時間輪的升級版本,來應對時間“槽”數量比較大的情況,對記憶體和精度都有很高要求的情況。延遲任務的場景 ...
  • 前言 預設的 Identity 實體類型在大多數時候已經基本夠用,很多時候也只是稍微在 IdentityUser 類中增加一些自定義數據欄位,比如頭像。這次,我要向園友隆重介紹我魔改之後的 Identity 實體類,能支持一些特別風騷的操作。當然也完全相容內置的 UserManager、RoleMa ...
  • 1、結構型設計模式 2、適配器模式 3、類適配器 4、對象適配器 ...
  • isinstance和issubclass isinstance(obj,cls)檢查是否obj是否是類 cls 的對象 class Foo(object): pass obj = Foo() isinstance(obj, Foo) issubclass(sub, super)檢查sub類是否是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...