Hướng dẫn python static variable initialization - khởi tạo biến tĩnh python

Xem xét mã sau

class Foo:
    i = 1 # initialization
    def __init__[self]:
        self.i += 1

t = Foo[]
print[t.i]

Khi nào chính xác thì việc khởi tạo tôi diễn ra? Trước khi thực hiện phương thức init hoặc sau đó?i take place? Before the execution of the init method or after it?

Đã hỏi ngày 4 tháng 5 năm 2019 lúc 14:13May 4, 2019 at 14:13

DaviddavidDavid

2.42116 Huy hiệu bạc49 Huy hiệu đồng16 silver badges49 bronze badges

2

Before.

Phương pháp

Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
1 không được chạy cho đến khi
Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
2 được khởi tạo.
Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
3 được chạy bất cứ khi nào định nghĩa lớp trong mã

Bạn có thể thấy điều này bằng cách thêm các câu lệnh in:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']

Bản in nào:

Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__

Tuy nhiên, lưu ý rằng

Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
4 của bạn không sửa đổi thuộc tính lớp
Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
5.does not modify the class attribute
Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
5.

foo.i # This is 2
Foo.i # This is 1

Đã trả lời ngày 4 tháng 5 năm 2019 lúc 14:15May 4, 2019 at 14:15

Stephen Cstephen cStephen C

1.9181 Huy hiệu vàng17 Huy hiệu bạc28 Huy hiệu đồng1 gold badge17 silver badges28 bronze badges

4

Thuộc tính lớp được khởi tạo ngay lần đầu tiên bạn sử dụng tên lớp trong mã nguồn, bạn cũng sử dụng thuộc tính lớp trong mã bằng cách thực hiện

Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
6

class Foo:
    i = 1 # initialization
    def __init__[self]:
        #Use ClassName.attribute to access class attribute
        Foo.i += 1

#I used the Name of the class here, Foo.i will be 1
print[Foo.i]
#1

#Instantiated Foo
t = Foo[]

#Value of i changes to 2
print[t.i]
#2

Chepner

467K69 Huy hiệu vàng491 Huy hiệu bạc638 Huy hiệu Đồng69 gold badges491 silver badges638 bronze badges

Đã trả lời ngày 4 tháng 5 năm 2019 lúc 14:19May 4, 2019 at 14:19

5

Python hỗ trợ khái niệm lập trình hướng đối tượng. Khi chúng tôi muốn để lại một cái gì đó như một hằng số, chúng tôi sử dụng thuật ngữ "tĩnh". Trong Python, 'tĩnh' là cần thiết khi chúng tôi muốn tạo bất kỳ biến hoặc phương thức nào cho lớp, tức là được chia sẻ bởi tất cả các trường hợp [đối tượng] của lớp. Chúng tôi sẽ sử dụng một số ví dụ để cho bạn thấy sự cần thiết của các biến 'tĩnh' và cách tạo chúng. Nhưng trước khi chúng tôi bắt đầu với các biến tĩnh, bạn nên làm quen với các biến và các khái niệm lập trình hướng đối tượng như lớp và phiên bản.. When we want to leave something as a constant, we use the term "static." In Python, 'static' is needed when we want to create any variable or method for the class, i.e. shared by all instances [objects] of the class. We'll use some examples to show you the need for 'static' variables and how to create them.
But, before we get started with static variables, you should be familiar with variables and object-oriented programming concepts like class and instance.

Hãy ghé thăm lớp học và các đối tượng trước !!

Lớp học là gì?

Một lớp có thể được định nghĩa là một mẫu hoặc bản thiết kế [để tạo các đối tượng], cho phép dữ liệu được lưu trữ và làm việc hiệu quả. Nó cũng có thể được coi là một loại dữ liệu do người dùng xác định, với tập hợp các thuộc tính và điều kiện riêng của nó. Các thuộc tính và phương thức là các thuật ngữ được sử dụng để mô tả các thuộc tính., allowing data to be efficiently stored and worked on. It could also be assumed as a user-defined data type, with its own set of attributes and conditions. Attributes and methods are terms used to describe properties.

Đối tượng [ví dụ] là gì?

Một đối tượng là một thể hiện lớp, chứa tất cả các thuộc tính & nbsp; và các hàm được xác định trong mẫu [lớp] bao gồm các giá trị của chúng. [Giả sử nó là một biến được tạo cho một kiểu dữ liệu.]

Một lớp có thể chứa nhiều trường hợp, mỗi loại giữ một giá trị khác nhau cho các thuộc tính, giống như kiểu dữ liệu có thể có nhiều biến, mỗi biến chứa các giá trị khác nhau.

[Đừng nhầm lẫn giữa đối tượng và biến. Ví dụ trên chỉ là một ví dụ cho & nbsp; hiểu rõ hơn.]

Biến tĩnh là gì?

Các biến thể hiện có thể là duy nhất cho mỗi trường hợp, nhưng đôi khi & nbsp; một thuộc tính, phổ biến cho toàn bộ lớp là bắt buộc. Một biến tĩnh là một biến vẫn phổ biến cho toàn bộ lớp, tức là & nbsp; thay vì & nbsp; tạo một bản sao cho mỗi phiên bản, cùng một không gian bộ nhớ được chia sẻ bởi tất cả các trường hợp. Các biến tĩnh cũng được gọi là các biến được xác định bên trong lớp nhưng bên ngoài & nbsp; các phương thức.A static variable is a variable that remains common for the entire class, i.e. rather than creating a copy for each instance, the same memory space is shared by all instances. Static variables are also referred to as variables defined inside the class but outside the methods.

Vì các biến tĩnh được giới hạn trong một lớp, chúng còn được gọi là biến lớp. Cả một đối tượng đều không thể ảnh hưởng đến biến lớp, cũng như biến tĩnh có thể thay đổi điều kiện của một đối tượng.

Hãy xem hình ảnh dưới đây để hiểu rõ hơn về sự khác biệt giữa biến thể hiện và biến tĩnh:

Các tính năng của một biến tĩnh trong Python

1. Một biến tĩnh được gọi là biến lớp vì nó chỉ thuộc về lớp được xác định.

2. Tất cả các đối tượng của lớp chia sẻ cùng một bản sao của biến tĩnh.

Một ví dụ: một nhà máy đồ chơi

Hãy đi tham quan một nhà máy Lego. Giả sử rằng các khối Lego có cùng chiều rộng và chiều cao nhưng chiều dài và màu sắc khác nhau sẽ được sản xuất.batch of lego blocks with the same width and height but varying length and color is to be manufactured.

Chúng ta hãy cố gắng phát triển một mã cho lớp này-một lớp-có thể được coi là một kế hoạch chi tiết chứa các thuộc tính phổ biến của một khối Lego. Mỗi khối LEGO sẽ là đối tượng của lớp này vì nó là bản sao của bản thiết kế nhưng với các giá trị. Và chiều rộng và chiều cao là các biến tĩnh cho lớp vì chúng không đổi [và phổ biến] cho tất cả các khối Lego của một lô.
A class can be assumed as a blueprint containing the common attributes of a lego block. Each lego block will be the object of this class since it is a copy of the blueprint but with values. And width and height are the static variables for the class as they remain constant [and common] for all lego blocks of a batch.

Chúng tôi hy vọng đây là một ví dụ dễ dàng để giúp bạn học cách nhận biết các biến tĩnh từ một vấn đề.

Bây giờ, chúng ta hãy tìm hiểu cách tạo và truy cập một biến tĩnh trong Python bằng cách sử dụng nhà máy đồ chơi.

Làm thế nào để tạo một biến tĩnh trong Python?

Ngôn ngữ lập trình luôn cung cấp nhiều phương pháp để thực hiện một nhiệm vụ. & NBSP; Có nhiều cách tiếp cận để tạo một biến tĩnh trong Python. Hãy xem một vài trong số họ -

Phương pháp 1: Khai thác biến trong lớp

Nếu bạn quen thuộc với các ngôn ngữ lập trình khác, bạn sẽ biết việc sử dụng từ khóa 'tĩnh' để khai báo các biến tĩnh. & NBSP; Python không có từ khóa 'tĩnh' để khai báo biến tĩnh. & NBSP;

Trong Python, Yousimply khai báo một biến bên trong lớp, lưu ý rằng nó không nên nằm trong bất kỳ phương pháp nào và biến đó sẽ được gọi là & nbsp; một biến tĩnh hoặc lớp. Khá dễ dàng, phải không?simply declare a variable inside the class, note that it should not be inside any method, and that variable will be known as a static or class variable. Pretty easy, right?

Hãy thử tạo mã cho nhà máy đồ chơi giả thuyết của chúng tôi -

#Creating a blueprint [class] for lego blocks
#Consider the dimensional unit to be in centimeters
class Lego:
    #Declare the static variables
    width = 5   #static variable
    height = 5  #static variable
    
    #Declaring a constructor, taking length and colour as a parameter
    #Remember 'self'[object] is passed to each method
    def __init__[self, length, colour]:
        self.length = length #instance variable
        self.colour = colour
        print['Block of ' +colour +' colour is manufactured.']

#Creating a lego block [object] of class Lego 
block1 = Lego[10, 'Red']
block2 = Lego[5, 'Blue']

Bạn sẽ nhận thấy rằng các thuộc tính, chiều rộng và chiều cao, là các biến tĩnh vì chúng được cho là không đổi [hoặc phổ biến] trong toàn bộ lớp. .

Block of Red colour is manufactured.
Block of Blue colour is manufactured.

Phương pháp trên là cách tiếp cận dễ nhất để tạo một biến tĩnh.

Phương pháp 2: Sử dụng phương thức HasAttr []

Python cũng cung cấp một phương thức hasAttr [], một phương thức được xây dựng để kiểm tra xem đối tượng [đối số được truyền] có thuộc tính đã cho hay không. Nó trả về true if & nbsp; đối tượng có thuộc tính đã cho [thuộc tính] khác nó trả về sai. Có hai cách để sử dụng phương thức hasAttr []-

một. Sử dụng phương thức hasAttr [] trong hàm tạoUsing hasattr[] method in Constructor

Chúng ta có thể tạo một biến tĩnh & nbsp; bằng cách sử dụng phương thức hasAttr [] bên trong hàm tạo để kiểm tra xem biến lớp [biến tĩnh] có được tạo hay không. & Nbsp; bạn nên biết rằng chúng ta có thể truy cập các biến tĩnh bằng định dạng - "className. staticvarable "."className.staticVariable".

& nbsp; chúng ta hãy xem mã bên dưới về cách khai báo một biến tĩnh bằng phương thức hasAttr [] trong hàm tạo-Let's have a look at the code below on how to declare a static variable using hasattr[] method in Constructor-

#Creating a blueprint [class] for lego blocks
#Consider the dimensional unit to be in centimeters
class Lego:
    
    #Declaring a constructor, taking length and colour as a parameter
    #Remember 'self'[object] is passed to each method
    def __init__[self, length, colour]:
        #Checking whether class Lego has attribute width or not
        if not hasattr[Lego, 'width']:
            print['Static variable created']
            Lego.width = 5  #class/static variable
        if not hasattr[Lego, 'height']:
            print['Static variable created']
            Lego.height = 5     #class/static variable
            
        self.length = length
        self.colour = colour
        print['Block of ' +colour +' colour is manufactured.']

#Creating a lego block [object] of class Lego 
block1 = Lego[10, 'Red']
block2 = Lego[5, 'Blue']

Chúng tôi đã sử dụng 'không hasattr []' vì vì tham số được truyền [nghĩa là Lego lớp của chúng tôi] không có thuộc tính 'chiều rộng' và 'chiều cao'. Vì vậy, phương pháp này trả về sai khi chúng tôi tạo phiên bản đầu tiên của chúng tôi. Tôi đã thêm một câu lệnh in trong cả hai khối để quan sát tốt hơn. Đầu ra xảy ra khi-not hasattr[]' because since the parameter passed [i.e. our class Lego] does not have the attribute 'width' and 'height'. So, this method returns false when we create our first instance. I have added a print statement in both the if-blocks for better observation. The output occurs as-

Static variable created
Static variable created
Block of Red colour is manufactured.
Block of Blue colour is manufactured.

Bạn sẽ tự hỏi tại sao dòng 'biến tĩnh được tạo' không được lặp lại sau khi tạo đối tượng đầu tiên [block1]? Đó là bởi vì một khi các biến 'chiều rộng' và 'chiều cao' được tạo cho & nbsp; lớp Lego, thì khi phương thức hasattr [] được gọi lại, nó & nbsp; trả về sai, tức là Lego lớp đã có các thuộc tính được đề cập.

b. Sử dụng phương thức hasAttr [] bên trong một phương thức

Phương pháp này rất hữu ích khi bạn chỉ phải tạo một biến tĩnh khi một phương thức nhất định được gọi. Giả sử rằng một biến tĩnh có tên 'khối' sẽ được thêm vào lớp của chúng tôi. Chúng ta có thể tạo một phương thức, giới thiệu biến 'khối' cho chúng ta. Kiểm tra mã dưới đây để có tài liệu tham khảo tốt hơn -& nbsp;

#Creating a blueprint [class] for lego blocks
#Consider the dimensional unit to be in centimeters
class Lego:
    
    #Declaring a constructor, taking length and colour as a parameter
    #Remember 'self'[object] is passed to each method
    def __init__[self, length, colour]:
        self.length = length
        self.colour = colour
        print['Block of ' +colour +' colour is manufactured.']
    
    #Using method to create a static variable
    def staticMethod[self]:
        if not hasattr[Lego, 'blocks']: #using hasattr[] method
            Lego.blocks = 12    #creating the class variable
            print['Lego blocks staic variable is created']

#Creating a lego block [object] of class Lego 
block1 = Lego[10, 'Red']
block2 = Lego[5, 'Blue']
#print[block1.blocks] block1.staticMethod[] print[block1.blocks] #accessing blocks static variable using object print[block2.blocks] #accessing blocks static variable using object

Bạn sẽ nhận thấy rằng nếu tôi chạy bình luận #print [block1.blocks] trước khi gọi staticMethod [] đã tạo, nó sẽ cho chúng tôi một lỗi vì biến tĩnh 'khối' sẽ không được tạo cho đến khi bạn gọi Phương thức.Output: & nbsp;
Output: 

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
0

Bạn có nhận thấy cách chúng tôi không gọi staticMethod [] thông qua đối tượng thứ hai của chúng tôi, nhưng nó có thể truy cập biến 'khối'? Do đó, chứng minh rằng biến tĩnh của chúng tôi được tạo ra.

Mọi người thường bị nhầm lẫn giữa & nbsp; các phương pháp để tạo các biến tĩnh và phương thức tĩnh. Lần tới khi bạn thấy một phương thức trong một lớp được thực hiện bằng cách sử dụng @staticmethod hoặc @ClassMethod, đừng nhầm lẫn! Nó chỉ là một cách tạo ra một biến tĩnh bằng phương pháp tĩnh. Chà, đó là một chủ đề dài !!

Làm thế nào để truy cập các biến tĩnh trong Python?

Cho đến nay, chúng tôi đã học được cách tạo một biến tĩnh; Bây giờ chúng ta hãy xem cách truy cập các biến tĩnh này để chúng ta có thể sử dụng chúng.

Phương pháp 1: Sử dụng tên lớp

Chúng tôi có thể trực tiếp gọi cho một biến tĩnh [biến lớp] bằng tên lớp. Có thể có hai trường hợp sử dụng cho cùng

[i] Truy cập biến tĩnh trong lớp

[ii] Gọi biến tĩnh trong phương pháp chính

Cả hai phương thức được hiển thị dưới đây:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
1

Output:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
2

Lưu ý cách các biến tĩnh được truy cập cả, bên trong và bên ngoài lớp, sử dụng tên lớp.

Phương pháp 2: Sử dụng tên đối tượng

Một biến lớp cũng có thể được gọi bằng cách sử dụng tên của đối tượng. Hãy xem mã dưới đây: & nbsp;

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
3

Output:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
4

Hãy nhớ rằng trong Python, bạn chỉ có thể truy cập các biến tĩnh thông qua các đối tượng. Bạn không thể thay đổi biến tĩnh bằng cách sử dụng một thể hiện của lớp. Ví dụ -& nbsp;

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
5

Trong mã trên, chúng tôi đã cố gắng thay đổi giá trị của biến tĩnh 'chiều rộng' bằng cách sử dụng đối tượng 'Block1'. Đầu ra:
Output:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
6

Hãy nhớ rằng bạn không thể thay đổi biến tĩnh với đối tượng. Nó sẽ chỉ tạo một thể hiện mới của biến đó cho đối tượng. Điều này sẽ không ảnh hưởng đến toàn bộ lớp.

Phương pháp 3: Sử dụng phương thức __ class__

Một cách khác để truy cập một biến tĩnh là sử dụng phương thức __ class__. & Nbsp; bạn có thể truy cập biến tĩnh bằng cách gọi điều này với sự trợ giúp của một đối tượng. Tên lớp. Hãy xem việc triển khai của nó dưới đây:
Basic Syntax:
objectName.__class__.staticVariableName
It can be termed as indirectly accessing the static variable using the class name. Let's see its implementation below:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
7

Lớp__. gọi cho lớp của phiên bản [Block1] và do đó trả về giá trị của biến 'chiều rộng' lấy lớp [LEGO] làm tài liệu tham khảo. & nbsp;.__class__. calls for the class of the instance [block1] and hence returns the value of the 'width' variable taking the class [Lego] as reference. 

Output:

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
8

Phương pháp 4: Sử dụng phương thức loại []

Phương pháp này có thể được xem như là một cuộc gọi gián tiếp đến biến tĩnh thông qua lớp. Phương thức loại [] trả về kiểu dữ liệu của biến chúng tôi truyền dưới dạng đối số cho nó. Hãy nhớ làm thế nào chúng ta nói về lớp là một loại dữ liệu do người dùng xác định? Kết quả là, khi một đối tượng được truyền dưới dạng đối số cho phương thức loại [], nó sẽ trả về lớp. Hãy nhìn vào cú pháp bên dưới -

print['Before Foo']
class Foo:
    i = 1
    print[f'Foo.i is now {i}']
    
    def __init__[self]:
        print['Inside __init__']
        self.i += 1
        print[f'i is now {self.i}']
print['After Foo']

print['Before __init__']
foo = Foo[]
print['After __init__']
9

Output:

Before Foo
Foo.i is now 1
After Foo
Before __init__
Inside __init__
i is now 2
After __init__
0

Sự kết luận

Các phương pháp được liệt kê ở trên là những cách đơn giản để tạo và truy cập một biến tĩnh trong Python. Điều đáng chú ý là việc truy cập vào biến tĩnh trực tiếp bằng tên của nó được coi là truy cập không chính xác và có thể dẫn đến các lỗi trong chương trình của bạn. Bạn cũng sẽ tìm thấy một vài phương pháp thử nghiệm thử trong khi xử lý các phương thức tĩnh trong Python. Các phương pháp này chỉ đơn giản là một cách khác để tạo và truy cập các biến tĩnh. Có nhiều cách khác trong đó các biến tĩnh có thể được tạo và truy cập. Chúng tôi để nó cho bạn để khám phá thêm về họ!

Bài Viết Liên Quan

Chủ Đề