ถ้าฉันมีรหัสหลามต่อไปนี้:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
มันบ่น
NameError: global name 'bar' is not defined
ฉันจะเข้าถึงตัวแปร class / static ได้อย่างไรbar
ภายใน method bah
?
ถ้าฉันมีรหัสหลามต่อไปนี้:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
มันบ่น
NameError: global name 'bar' is not defined
ฉันจะเข้าถึงตัวแปร class / static ได้อย่างไรbar
ภายใน method bah
?
คำตอบ:
แทนการbar
ใช้หรือself.bar
Foo.bar
การกำหนดให้กับFoo.bar
จะสร้างตัวแปรแบบสแตติกและการกำหนดให้กับself.bar
จะสร้างตัวแปรอินสแตนซ์
กำหนดวิธีการเรียน:
class Foo(object):
bar = 1
@classmethod
def bah(cls):
print cls.bar
ตอนนี้ถ้าbah()
จะต้องมีวิธีการอินสแตนซ์ (เช่นมีการเข้าถึงตนเอง) คุณยังสามารถเข้าถึงตัวแปรคลาสได้โดยตรง
class Foo(object):
bar = 1
def bah(self):
print self.bar
เช่นเดียวกับตัวอย่างที่ดีทั้งหมดคุณทำให้สิ่งที่คุณพยายามทำง่ายขึ้น นี่เป็นสิ่งที่ดี แต่มันก็คุ้มที่จะสังเกตว่าหลามนั้นมีความยืดหยุ่นอย่างมากเมื่อพูดถึงตัวแปร class กับอินสแตนซ์ เดียวกันสามารถพูดถึงวิธีการ สำหรับรายการความเป็นไปได้ที่ดีฉันขอแนะนำให้อ่านการแนะนำสไตล์แบบใหม่ของ Michael Fötschโดยเฉพาะอย่างยิ่งส่วนที่ 2 ถึง 6
สิ่งหนึ่งที่ต้องใช้ความพยายามอย่างมากในการเริ่มต้นคือpython ไม่ใช่จาวา มากกว่าแค่ถ้อยคำที่เบื่อหู ใน java คลาสทั้งหมดถูกคอมไพล์ทำให้ความละเอียดของเนมสเปซง่ายจริง: ตัวแปรใด ๆ ที่ประกาศนอกเมธอด (ที่ใดก็ได้) เป็นอินสแตนซ์ (หรือถ้าคงที่คลาส) ตัวแปรและเข้าถึงได้โดยปริยายภายในเมธอด
ด้วยไพ ธ อนกฎข้อใหญ่คือมีสามเนมสเปซที่ค้นหาตามลำดับสำหรับตัวแปร:
{begin pedagogy}
มีข้อยกเว้นที่ จำกัด ในเรื่องนี้ หลักสำคัญที่เกิดขึ้นกับฉันคือเมื่อโหลดคลาสนิยามแล้วนิยามคลาสคือเนมสเปซของตัวเอง แต่จะคงอยู่เพียงตราบเท่าที่โมดูลกำลังถูกโหลดและจะถูกข้ามโดยสิ้นเชิงเมื่ออยู่ภายในเมธอด ดังนั้น:
>>> class A(object):
foo = 'foo'
bar = foo
>>> A.foo
'foo'
>>> A.bar
'foo'
แต่:
>>> class B(object):
foo = 'foo'
def get_foo():
return foo
bar = get_foo()
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
class B(object):
File "<pyshell#11>", line 5, in B
bar = get_foo()
File "<pyshell#11>", line 4, in get_foo
return foo
NameError: global name 'foo' is not defined
{end pedagogy}
ในท้ายที่สุดสิ่งที่ต้องจำไว้คือคุณไม่ได้มีการเข้าถึงตัวแปรใด ๆ ที่คุณต้องการเข้าถึง แต่อาจจะไม่ได้โดยปริยาย หากเป้าหมายของคุณเรียบง่ายและตรงไปตรงมาการไปหา Foo.bar หรือ self.bar อาจจะเพียงพอ หากตัวอย่างของคุณมีความซับซ้อนมากขึ้นหรือคุณต้องการทำสิ่งที่แปลกใหม่เช่นการสืบทอด (คุณสามารถสืบทอดวิธีการคงที่ / คลาส!) หรือความคิดในการอ้างถึงชื่อคลาสของคุณภายในคลาสนั้นดูเหมือนผิดกับคุณ คำนำที่ฉันเชื่อมโยง
class Foo(object):
bar = 1
def bah(self):
print Foo.bar
f = Foo()
f.bah()
class Foo(object):
bar = 1
def bah(object_reference):
object_reference.var = Foo.bar
return object_reference.var
f = Foo()
print 'var=', f.bah()