天天看點

學習python:day71.反射的定義2. 反射的函數

靜态方法

靜态方法是一種普通函數,就位于類定義的命名空間中,它不會對任何執行個體類型進行操作。使用裝飾器@staticmethod定義靜态方法。類對象和執行個體都可以調用靜态方法;

說了那麼多,估計會有些懵逼,咱們還是直接上代碼看下靜态方法怎麼使用吧!

1.按照正常邏輯編寫代碼并加上@staticmethod定義靜态方法eat:

1 2 3 4 5 6 7 8 9 10

class

People(

object

):

def

__init__(

self

,name):

self

.name 

=

name

@staticmethod

#把eat方法變為靜态方法

def

eat(

self

):

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat()

運作上面代碼,我們會發現報以下錯誤:

TypeError: eat() missing 1 required positional argument: 'self'

----------eat需要一個self參數,但調用時卻沒有傳遞

so...我們可以得出一個結論:eat變成靜态方法後,再通過執行個體調用時不會自動把執行個體本身當作一個參數傳給self

2.解決辦法:

1)調用時主動傳遞執行個體本身給eat方法,即d.eat(d) 

1 2 3 4 5 6 7 8 9 10 11

class

People(

object

):

def

__init__(

self

, name):

self

.name 

=

name

@staticmethod

# 把eat方法變為靜态方法

def

eat(

self

):

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat(d)

#------列印輸出------

#cc is eating

2)在eat方法中去掉self參數(這也意味着,在eat中不能通過self.調用執行個體中的其它變量了)

1 2 3 4 5 6 7 8 9 10 11 12 13

class

People(

object

):

def

__init__(

self

, name):

self

.name 

=

name

@staticmethod

# 把eat方法變為靜态方法

def

eat():

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat()

#------------------列印輸出----------------

#print("%s is eating" % self.name)

#NameError: name 'self' is not defined

類方法

類方法是将類本身作為對象進行操作的方法。類方法使用@classmethod裝飾器定義,其第一個參數是類,約定寫為cls。類對象和執行個體都可以調用類方法。

類方法和普通方法的差別是, 類方法隻能通路類變量,不能通路執行個體變量。

依然還是原來的代碼,把eat變為類方法看下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14

class

People(

object

):

def

__init__(

self

, name):

self

.name 

=

name

@classmethod

# 把eat方法變為類方法

def

eat(

self

):

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat()

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

print

(

"%s is eating"

%

self

.name)

AttributeError: 

type

object

'People'

has no attribute 

'name'

報錯說明:People沒有name屬性;

上面說過,類方法隻能通路類變量,不能通路執行個體變量,而name在這裡就是執行個體變量。

我們加上一個類變量試試:

1 2 3 4 5 6 7 8 9 10 11 12 13

class

People(

object

):

name 

=

"類變量"

def

__init__(

self

, name):

self

.name 

=

name

@classmethod

# 把eat方法變為類方法

def

eat(

self

):

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat()

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

類變量 

is

eating

屬性方法

屬性方法的作用就是通過@property把一個方法變成一個靜态屬性;

依然還是之前的代碼,把eat方法變成靜态屬性看下效果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

class

People(

object

):

name 

=

"請叫我類變量"

def

__init__(

self

, name):

self

.name 

=

name

@property

# 把eat方法變為靜态屬性

def

eat(

self

):

print

(

"%s is eating"

%

self

.name)

=

People(

"cc"

)

d.eat()

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

d.eat()

TypeError: 

'NoneType'

object

is

not

callable

這裡報錯是因為eat已經變成了一個靜态方法,當然不能再使用()去調用了,我們直接調用試試:

1 2 3 4

d.eat

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

cc 

is

eating

反射

1.反射的定義

根據字元串的形式去某個對象中操作成員

  • 根據字元串的形式去一個對象中尋找成員
  • 根據字元串的形式去一個對象中設定成員
  • 根據字元串的形式去一個對象中删除成員
  • 根據字元串的形式去一個對象中判斷成員是否存在

2. 反射的函數

  • getattr(object, name[, default])

根據字元串的形式去一個對象中尋找成員

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

class

People(

object

):

def

__init__(

self

):

self

.name 

=

'cc'

def

eat(

self

):

return

'HI'

=

People()

ret1 

=

getattr

(d,

'eat'

)

ret2 

=

getattr

(d,

'name'

)

r1 

=

ret1()

print

(r1)

print

(ret2)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

HI

cc

  • setattr(object, name, value)

根據字元串的形式去一個對象中設定成員

1 2 3 4 5 6 7 8 9 10 11 12

class

People(

object

):

def

__init__(

self

):

self

.name 

=

'cc'

def

eat(

self

):

return

'HI'

=

People()

set1 

=

setattr

(d,

'age'

,

18

)

r1 

=

getattr

(d,

'age'

)

print

(r1)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

18

  • delattr(object, name)

根據字元串的形式去一個對象中删除成員

1 2 3 4 5 6 7 8 9 10 11 12

class

People(

object

):

def

__init__(

self

):

self

.name 

=

'cc'

def

eat(

self

):

return

'HI'

=

People()

del1 

=

delattr

(d,

'name'

)

r1 

=

getattr

(d,

'name'

)

print

(r1)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

AttributeError: 

'People'

object

has no attribute 

'name'

  • hasattr(object, name)

根據字元串的形式去一個對象中判斷成員是否存在

1 2 3 4 5 6 7 8 9 10 11 12

class

People(

object

):

def

__init__(

self

):

self

.name 

=

'cc'

def

eat(

self

):

return

'HI'

=

People()

h1 

=

hasattr

(d,

'age'

)

h2 

=

hasattr

(d,

'name'

)

print

(h1,h2)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

False

True

異常處理

在之前學習的過程中我們會接觸到各式各樣的報錯資訊,程式設計過程中為了增加友好性,可以抓取相對應的錯誤并給出提示資訊。

常用異常:

1 2 3 4 5 6 7 8 9 10 11 12 13

AttributeError 試圖通路一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x

IOError 輸入

/

輸出異常;基本上是無法打開檔案

ImportError 無法引入子產品或包;基本上是路徑問題或名稱錯誤

IndentationError 文法錯誤(的子類) ;代碼沒有正确對齊

IndexError 下标索引超出序列邊界,比如當x隻有三個元素,卻試圖通路x[

5

]

KeyError 試圖通路字典裡不存在的鍵

KeyboardInterrupt Ctrl

+

C被按下

NameError 使用一個還未被賦予對象的變量

SyntaxError Python代碼非法,代碼不能編譯(個人認為這是文法錯誤,寫錯了)

TypeError 傳入對象類型與要求的不符合

UnboundLocalError 試圖通路一個還未被設定的局部變量,基本上是由于另有一個同名的全局變量,

導緻你以為正在通路它

ValueError 傳入一個調用者不期望的值,即使值的類型是正确的

更多異常:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

ArithmeticError

AssertionError

AttributeError

BaseException

BufferError

BytesWarning

DeprecationWarning

EnvironmentError

EOFError

Exception

FloatingPointError

FutureWarning

GeneratorExit

ImportError

ImportWarning

IndentationError

IndexError

IOError

KeyboardInterrupt

KeyError

LookupError

MemoryError

NameError

NotImplementedError

OSError

OverflowError

PendingDeprecationWarning

ReferenceError

RuntimeError

RuntimeWarning

StandardError

StopIteration

SyntaxError

SyntaxWarning

SystemError

SystemExit

TabError

TypeError

UnboundLocalError

UnicodeDecodeError

UnicodeEncodeError

UnicodeError

UnicodeTranslateError

UnicodeWarning

UserWarning

ValueError

Warning

ZeroDivisionError

常用異常執行個體:

IndexError(輸出指定錯誤資訊并列印錯誤資訊)

1 2 3 4 5 6 7 8 9

dic 

=

[

1

,

2

]

try

:

dic[

2

]

except

IndexError as e :

print

(

"i got it!\n"

,e)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

i got it!

list

index out of 

range

KeyError(輸出指定錯誤資訊并列印錯誤資訊)

1 2 3 4 5 6 7 8 9 10

dic 

=

{

'name'

:

'cc'

}

try

:

dic[

'age'

]

except

KeyError as e :

print

(

"i got it!\n"

,e)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

i got it!

'age'

ValueError

1 2 3 4 5 6 7 8 9

s1 

=

'hello'

try

:

int

(s1)

except

ValueError as e:

print

(e)

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

列印輸出

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

invalid literal 

for

int

() with base 

10

'hello'

萬能異常Exception:(不建議用,不便于調試;可與異常配合使用)

1 2 3 4 5 6 7 8 9

s1 

=

'hello'

try

:

int

(s1)

except

KeyError as e:

print

(

'鍵錯誤'

)

except

IndexError as e:

print

(

'索引錯誤'

)

except

Exception as e:

print

(

'錯誤'

)

自定義異常:

1 2 3 4 5 6 7 8 9

class

ccException(Exception):

def

__init__(

self

,msg):

self

.msg 

=

msg

def

__str__(

self

):

return

self

.msg

try

:

raise

ccException(

"我的異常"

)

except

ccException as e:

print

(e)<span style

=

"font-size: 14pt;"

> <

/

span>

轉載于:https://www.cnblogs.com/liuyuchen123456/p/5855894.html