41
Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.
Tôi muốn tạo ra một lớp học trong Python quản lý trên tất cả các thành viên tĩnh. Những thành viên này nên được khởi xướng trong khi định nghĩa lớp học. Do thực tế là sẽ có yêu cầu tái tạo các thành viên tĩnh sau này, tôi sẽ đặt mã này vào một lớp.
Câu hỏi của tôi: Làm thế nào tôi có thể gọi lớp học này từ bên trong lớp?
class Test[]:
# static member
x = None
# HERE I WOULD LOVE TO CALL SOMEHOW static_init!
# initialize static member in classmethod, so that it can be
#reinitialized later on again
@classmethod
def static_init[cls]:
cls.x = 10
Bất kỳ sự giúp đỡ được đánh giá cao!
Cảm ơn trước, Volker
Hỏi ngày 16 tháng 12 năm 2012 lúc 10:47Dec 16, 2012 at 10:47
2
Vào thời điểm
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
4 được thực thi trong ví dụ của bạn, không chỉ lớp không tồn tại, mà lớp học cũng không tồn tại.Thực hiện trong Python đi từ trên xuống dưới. Nếu
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
4 ở trên lớp, không có cách nào bạn có thể truy cập vào lớp học tại thời điểm đó, vì nó chưa được xác định.Ngay cả khi bạn có thể chạy lớp học, điều đó sẽ không quan trọng, bởi vì lớp chưa tồn tại, vì vậy ClassMethod không thể đề cập đến nó. Lớp không được tạo cho đến khi toàn bộ khối lớp chạy, vì vậy trong khi bạn ở trong khối lớp, không có lớp.
Nếu bạn muốn đưa ra một số khởi tạo lớp để bạn có thể chạy lại sau theo cách bạn mô tả, hãy sử dụng một bộ trang trí lớp. Nhà trang trí lớp chạy sau khi lớp được tạo, vì vậy nó có thể gọi lớp học tốt.
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
Đã trả lời ngày 16 tháng 12 năm 2012 lúc 11:32Dec 16, 2012 at 11:32
BrenbarnbrenbarnBrenBarn
233K35 Huy hiệu vàng397 Huy hiệu bạc375 Huy hiệu Đồng35 gold badges397 silver badges375 bronze badges
4
Bạn gọi một phương thức lớp bằng cách nối thêm tên lớp tương tự:
class.method
Trong mã của bạn, một cái gì đó như thế này là đủ:
Test.static_init[]
Bạn cũng có thể làm điều này:
static_init[Test]
Để gọi nó bên trong lớp của bạn, hãy yêu cầu mã của bạn làm điều này:, have your code do this:
Test.static_init[]
Mã làm việc của tôi:
class Test[object]:
@classmethod
def static_method[cls]:
print["Hello"]
def another_method[self]:
Test.static_method[]
và
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
6 trả về >>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
7Đã trả lời ngày 16 tháng 12 năm 2012 lúc 10:51Dec 16, 2012 at 10:51
NlightnfotisnlightnfotisNlightNFotis
9.4135 Huy hiệu vàng41 Huy hiệu bạc65 Huy hiệu Đồng5 gold badges41 silver badges65 bronze badges
4
Bạn không thể gọi
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
8 theo định nghĩa >>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
9 vì lớp chưa được xác định đầy đủ, vì vậy không có gì để vượt qua phương pháp như đối số class.method
0 đầu tiên của nó ... một vấn đề gà và trứng cổ điển. Tuy nhiên, bạn có thể làm việc xung quanh giới hạn này bằng cách quá tải phương thức class.method
1 trong Metaclass và gọi ClassMethod từ đó sau khi lớp được tạo như minh họa dưới đây:class Test[object]:
# nested metaclass definition
class __metaclass__[type]:
def __new__[mcl, classname, bases, classdict]:
cls = type.__new__[mcl, classname, bases, classdict] # creates class
cls.static_init[] # call the classmethod
return cls
x = None
@classmethod
def static_init[cls]: # called by metaclass when class is defined
print["Hello"]
cls.x = 10
print Test.x
Output:
Hello
10
Đã trả lời ngày 16 tháng 12 năm 2012 lúc 12:11Dec 16, 2012 at 12:11
Martineaumartineaumartineau
Huy hiệu vàng 116K2525 gold badges160 silver badges285 bronze badges
Sau khi đọc lại câu hỏi của bạn lần này tôi có thể nghĩ về hai giải pháp. Đầu tiên là áp dụng mẫu thiết kế Borg. Cái thứ hai là loại bỏ phương thức lớp và sử dụng hàm cấp mô -đun thay thế. Điều này dường như để giải quyết vấn đề của bạn:carefully this time I can think of two solutions. The first one is to apply the Borg design pattern. The second one is to discard the class method and use a module level function instead. This appears to solve your problem:
def _test_static_init[value]:
return value, value * 2
class Test:
x, y = _test_static_init[20]
if __name__ == "__main__":
print Test.x, Test.y
Câu trả lời cũ, không chính xác:
Đây là một ví dụ, tôi hy vọng nó sẽ giúp:
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
0Dù sao, câu trả lời của NLightNFotis là một câu hỏi hay hơn: Sử dụng tên lớp khi truy cập các phương thức lớp. Nó làm cho mã của bạn ít mơ hồ hơn.
Đã trả lời ngày 16 tháng 12 năm 2012 lúc 11:12Dec 16, 2012 at 11:12
ZalewaplzalewaplZalewaPL
1.1041 huy hiệu vàng6 Huy hiệu bạc14 Huy hiệu đồng1 gold badge6 silver badges14 bronze badges
4
Đây có vẻ như là một giải pháp hợp lý:
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
1Phương pháp này bây giờ là một phương pháp tĩnh của mật mã, không có gì bên ngoài các lớp được tham chiếu. Thay vào đó, bạn có thể chọn đặt tên
class.method
2 class.method
3, nếu bạn không muốn mọi người sử dụng nó.Lưu ý: Tôi đã xóa
class.method
4, khi tôi chạy nó vào 3.7, nhưng sau khi đọc tài liệu về Final, tôi không nghĩ nó sẽ ảnh hưởng đến giải pháp? Cũng đã thêm một nhập khẩu cho class.method
5 mà câu hỏi đã bị thiếu. Và cuối cùng đã thêm một triển khai cho các phương thức trừu tượng, thay vào đó, cũng có thể để cho Vigenerecodes kế thừa từ class.method
6.Đã trả lời ngày 25 tháng 12 năm 2019 lúc 1:48Dec 25, 2019 at 1:48
GrismargrismarGrismar
24.1k4 Huy hiệu vàng30 Huy hiệu bạc 50 Huy hiệu Đồng4 gold badges30 silver badges50 bronze badges
lớp người với add [] @classmethod
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
2Đã trả lời ngày 22 tháng 11 năm 2020 lúc 6:55Nov 22, 2020 at 6:55
Nếu lớp học của bạn không được sử dụng rất thường xuyên, hãy đánh giá lười biếng
>>> def deco[cls]:
... cls.initStuff[]
... return cls
>>> @deco
... class Foo[object]:
... x = 10
...
... @classmethod
... def initStuff[cls]:
... cls.x = 88
>>> Foo.x
88
>>> Foo.x = 10
>>> Foo.x
10
>>> Foo.initStuff[] # reinitialize
>>> Foo.x
88
3Đã trả lời ngày 14 tháng 11 năm 2021 lúc 18:28Nov 14, 2021 at 18:28
Wolfgang Fahlwolfgang FahlWolfgang Fahl
Phù bằng vàng 14K99 gold badges86 silver badges168 bronze badges